From 1f5e8a462908a7c6e7eac5b53c70749837d29c64 Mon Sep 17 00:00:00 2001 From: floydinator-git <78954063+floydinator-git@users.noreply.github.com> Date: Tue, 10 Sep 2024 23:04:09 -0400 Subject: [PATCH 001/181] Fix ImageMetadataDatabase::calculateImageSize calling Image::readPngMetadata on non-PNG images. --- source/core/StarImage.cpp | 6 ++++++ source/core/StarImage.hpp | 1 + source/game/StarImageMetadataDatabase.cpp | 6 +++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/source/core/StarImage.cpp b/source/core/StarImage.cpp index 82e3b05..52c2370 100644 --- a/source/core/StarImage.cpp +++ b/source/core/StarImage.cpp @@ -17,6 +17,12 @@ void readPngData(png_structp pngPtr, png_bytep data, png_size_t length) { ((IODevice*)png_get_io_ptr(pngPtr))->readFull((char*)data, length); }; +bool Image::isPng(IODevicePtr device) { + png_byte header[8]; + device->readAbsolute(0, (char*)header, sizeof(header)); + return !png_sig_cmp(header, 0, sizeof(header)); +} + Image Image::readPng(IODevicePtr device) { png_byte header[8]; device->readFull((char*)header, sizeof(header)); diff --git a/source/core/StarImage.hpp b/source/core/StarImage.hpp index 478d074..aac0105 100644 --- a/source/core/StarImage.hpp +++ b/source/core/StarImage.hpp @@ -27,6 +27,7 @@ STAR_CLASS(Image); class Image { public: static Image readPng(IODevicePtr device); + static bool isPng(IODevicePtr device); // Returns the size and pixel format that would be constructed from the given // png file, without actually loading it. static tuple readPngMetadata(IODevicePtr device); diff --git a/source/game/StarImageMetadataDatabase.cpp b/source/game/StarImageMetadataDatabase.cpp index bf84e51..d04e984 100644 --- a/source/game/StarImageMetadataDatabase.cpp +++ b/source/game/StarImageMetadataDatabase.cpp @@ -174,7 +174,11 @@ Vec2U ImageMetadataDatabase::calculateImageSize(AssetPath const& path) const { imageSize = *size; } else { locker.unlock(); - imageSize = get<0>(Image::readPngMetadata(assets->openFile(path.basePath))); + auto file = assets->openFile(path.basePath); + if (Image::isPng(file)) + imageSize = get<0>(Image::readPngMetadata(file)); + else + imageSize = fallback(); locker.lock(); m_sizeCache[path.basePath] = imageSize; } From 37f3178d33ab77de064bcbf10b4b03ddb47cc979 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 5 Sep 2024 19:15:47 +1000 Subject: [PATCH 002/181] Network compatibility changes --- .github/workflows/build.yml | 231 ++++++++++++++++++ .github/workflows/build_linux.yml | 76 ------ .github/workflows/build_macos.yml | 97 -------- .github/workflows/build_windows.yml | 89 ------- source/base/StarAssets.cpp | 2 +- source/core/CMakeLists.txt | 2 + source/core/StarDataStream.cpp | 7 + source/core/StarDataStream.hpp | 5 +- source/core/StarDataStreamDevices.hpp | 4 +- source/core/StarNetCompatibility.hpp | 41 ++++ source/core/StarNetElement.cpp | 4 +- source/core/StarNetElement.hpp | 30 ++- source/core/StarNetElementBasicFields.cpp | 4 +- source/core/StarNetElementBasicFields.hpp | 23 +- source/core/StarNetElementContainers.hpp | 45 +++- source/core/StarNetElementDynamicGroup.hpp | 40 +-- source/core/StarNetElementExt.hpp | 85 +++++++ source/core/StarNetElementFloatFields.hpp | 19 +- source/core/StarNetElementGroup.cpp | 41 +++- source/core/StarNetElementGroup.hpp | 8 +- source/core/StarNetElementSignal.hpp | 18 +- source/core/StarNetElementSyncGroup.cpp | 20 +- source/core/StarNetElementSyncGroup.hpp | 8 +- source/core/StarNetElementTop.hpp | 48 ++-- source/frontend/StarTeamBar.hpp | 7 +- source/game/StarClientContext.cpp | 15 +- source/game/StarClientContext.hpp | 8 +- source/game/StarEntityFactory.cpp | 44 ++-- source/game/StarEntityFactory.hpp | 4 +- source/game/StarHumanoid.cpp | 86 ++++--- source/game/StarHumanoid.hpp | 2 + source/game/StarItemDrop.cpp | 15 +- source/game/StarItemDrop.hpp | 8 +- source/game/StarMonster.cpp | 12 +- source/game/StarMonster.hpp | 6 +- source/game/StarMonsterDatabase.cpp | 10 +- source/game/StarMonsterDatabase.hpp | 6 +- source/game/StarNetPackets.cpp | 1 + source/game/StarNetPackets.hpp | 2 + source/game/StarNpc.cpp | 14 +- source/game/StarNpc.hpp | 7 +- source/game/StarNpcDatabase.cpp | 10 +- source/game/StarNpcDatabase.hpp | 8 +- source/game/StarObject.cpp | 12 +- source/game/StarObject.hpp | 6 +- source/game/StarObjectDatabase.cpp | 3 +- source/game/StarObjectDatabase.hpp | 2 +- source/game/StarPlant.cpp | 18 +- source/game/StarPlant.hpp | 8 +- source/game/StarPlantDrop.cpp | 13 +- source/game/StarPlantDrop.hpp | 8 +- source/game/StarPlayer.cpp | 14 +- source/game/StarPlayer.hpp | 8 +- source/game/StarPlayerFactory.cpp | 4 +- source/game/StarPlayerFactory.hpp | 2 +- source/game/StarProjectile.cpp | 13 +- source/game/StarProjectile.hpp | 8 +- source/game/StarProjectileDatabase.cpp | 5 +- source/game/StarProjectileDatabase.hpp | 2 +- source/game/StarServerClientContext.cpp | 9 +- source/game/StarServerClientContext.hpp | 4 +- source/game/StarSky.cpp | 8 +- source/game/StarSky.hpp | 4 +- source/game/StarStagehand.cpp | 13 +- source/game/StarStagehand.hpp | 8 +- source/game/StarStatusController.cpp | 77 ++++-- source/game/StarStatusController.hpp | 19 +- source/game/StarSystemWorld.cpp | 16 +- source/game/StarSystemWorld.hpp | 8 +- source/game/StarSystemWorldServer.cpp | 4 +- source/game/StarTechController.cpp | 18 +- source/game/StarTechController.hpp | 8 +- source/game/StarToolUser.cpp | 32 +-- source/game/StarToolUser.hpp | 8 +- source/game/StarUniverseClient.cpp | 19 +- source/game/StarUniverseClient.hpp | 1 - source/game/StarUniverseServer.cpp | 8 +- source/game/StarVehicle.cpp | 8 +- source/game/StarVehicle.hpp | 4 +- source/game/StarVehicleDatabase.cpp | 9 +- source/game/StarVehicleDatabase.hpp | 4 +- source/game/StarWeather.cpp | 8 +- source/game/StarWeather.hpp | 4 +- source/game/StarWorldClient.cpp | 28 ++- source/game/StarWorldClientState.cpp | 14 +- source/game/StarWorldClientState.hpp | 7 +- source/game/StarWorldServer.cpp | 33 +-- source/game/StarWorldServer.hpp | 3 +- source/game/StarWorldServerThread.cpp | 4 +- source/game/StarWorldServerThread.hpp | 2 +- .../game/interfaces/StarActivatableItem.hpp | 7 +- source/game/interfaces/StarEntity.cpp | 5 +- source/game/interfaces/StarEntity.hpp | 5 +- source/game/scripting/StarRootLuaBindings.cpp | 4 +- 94 files changed, 1008 insertions(+), 743 deletions(-) create mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/build_linux.yml delete mode 100644 .github/workflows/build_macos.yml delete mode 100644 .github/workflows/build_windows.yml create mode 100644 source/core/StarNetCompatibility.hpp create mode 100644 source/core/StarNetElementExt.hpp diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..60097c8 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,231 @@ +name: Build + +on: + workflow_dispatch: + + pull_request: + branches: + - "*" + +jobs: + build_windows: + name: Build OpenStarbound Windows x64 + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: 'recursive' + + - name: Install CMake & Ninja + uses: lukka/get-cmake@latest + with: + cmakeVersion: 3.29.2 + + - name: sccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + variant: sccache + key: ${{ github.job }}-${{ runner.os }} + max-size: 1000M + + - uses: ilammy/msvc-dev-cmd@v1 + + - name: vcpkg + uses: lukka/run-vcpkg@v11 + id: runvcpkg + with: + vcpkgJsonGlob: '**/source/vcpkg.json' + vcpkgConfigurationJsonGlob: '**/source/vcpkg-configuration.json' + + - name: Run CMake + uses: lukka/run-cmake@v10 + with: + cmakeListsTxtPath: '${{ github.workspace }}/source/CMakeLists.txt' + configurePreset: 'windows-release' + buildPreset: 'windows-release' + testPreset: 'windows-release' + + - name: Run Post-Build Task + working-directory: ${{ github.workspace }} + run: scripts\ci\windows\post_build.bat + + - name: Assemble Files + working-directory: ${{ github.workspace }} + run: scripts\ci\windows\assemble.bat + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: OpenStarbound-Windows-All-DevOnly + path: dist/* + + - name: Upload Client + uses: actions/upload-artifact@v4 + with: + name: OpenStarbound-Windows-Client + path: client_distribution/* + + - name: Upload Server + uses: actions/upload-artifact@v4 + with: + name: OpenStarbound-Windows-Server + path: server_distribution/* + + - name: Create Installer + working-directory: ${{ github.workspace }} + run: | + & "C:\Program Files (x86)\Inno Setup 6\iscc.exe" /Oinstaller scripts\inno\setup.iss + + - name: Upload Installer + uses: actions/upload-artifact@v4 + with: + name: OpenStarbound-Windows-Installer + path: installer/* + + build_linux: + name: Build OpenStarbound Linux x86_64 + runs-on: ubuntu-20.04 + + steps: + - name: Install Packages + run: | + sudo apt-get update + sudo apt-get install -y pkg-config libxmu-dev libxi-dev libgl-dev libglu1-mesa-dev libsdl2-dev + + - name: Install CMake & Ninja + uses: lukka/get-cmake@latest + with: + cmakeVersion: 3.29.2 + + - uses: actions/checkout@v4 + with: + submodules: 'recursive' + + - name: sccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + variant: sccache + key: ${{ github.job }}-${{ runner.os }} + max-size: 250M + + - name: vcpkg + uses: lukka/run-vcpkg@v11 + id: runvcpkg + with: + vcpkgJsonGlob: '**/source/vcpkg.json' + vcpkgConfigurationJsonGlob: '**/source/vcpkg-configuration.json' + + - name: Run CMake + uses: lukka/run-cmake@v10 + with: + cmakeListsTxtPath: '${{ github.workspace }}/source/CMakeLists.txt' + configurePreset: 'linux-release' + buildPreset: 'linux-release' + testPreset: 'linux-release' + + - name: Assemble Files + working-directory: ${{ github.workspace }} + run: scripts/ci/linux/assemble.sh + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: OpenStarbound-Linux + path: dist.tar + + - name: Upload Client Files + uses: actions/upload-artifact@v4 + with: + name: OpenStarbound-Linux-Client + path: client.tar + + - name: Upload Server Files + uses: actions/upload-artifact@v4 + with: + name: OpenStarbound-Linux-Server + path: server.tar + + build-mac-intel: + name: Build OpenStarbound macOS x86_64 + runs-on: macos-13 + + steps: + - uses: actions/checkout@v4 + with: + submodules: 'recursive' + + - name: Install CMake & Ninja + uses: lukka/get-cmake@latest + with: + cmakeVersion: 3.29.0 + + - name: sccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + variant: sccache + key: ${{ github.job }}-Intel-${{ runner.os }} + max-size: 250M + + - name: vcpkg + uses: lukka/run-vcpkg@v11 + id: runvcpkg + with: + vcpkgJsonGlob: '**/source/vcpkg.json' + vcpkgConfigurationJsonGlob: '**/source/vcpkg-configuration.json' + + - name: Run CMake + uses: lukka/run-cmake@v10 + with: + cmakeListsTxtPath: '${{ github.workspace }}/source/CMakeLists.txt' + configurePreset: 'macos-release' + buildPreset: 'macos-release' + testPreset: 'macos-release' + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: OpenStarbound-macOS-Intel + path: dist/* + + build-mac-arm: + name: Build OpenStarbound macOS arm64 + runs-on: macos-14 + + steps: + - uses: actions/checkout@v4 + with: + submodules: 'recursive' + + - name: Install CMake & Ninja + uses: lukka/get-cmake@latest + with: + cmakeVersion: 3.29.2 + + - name: sccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + variant: sccache + key: ${{ github.job }}-ARM-${{ runner.os }} + max-size: 250M + + - name: vcpkg + uses: lukka/run-vcpkg@v11 + id: runvcpkg + with: + vcpkgJsonGlob: '**/source/vcpkg.json' + vcpkgConfigurationJsonGlob: '**/source/vcpkg-configuration.json' + + - name: Run CMake + uses: lukka/run-cmake@v10 + with: + cmakeListsTxtPath: '${{ github.workspace }}/source/CMakeLists.txt' + configurePreset: 'macos-arm-release' + buildPreset: 'macos-arm-release' + testPreset: 'macos-arm-release' + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: OpenStarbound-macOS-Silicon + path: dist/* \ No newline at end of file diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml deleted file mode 100644 index 307b30f..0000000 --- a/.github/workflows/build_linux.yml +++ /dev/null @@ -1,76 +0,0 @@ -name: Ubuntu Linux - -on: - push: - branches: - - "*" - tags: - - "*" - - pull_request: - branches: - - "*" - -jobs: - build: - name: OpenStarbound Linux x86_64 - runs-on: ubuntu-20.04 - - steps: - - name: Install Packages - run: | - sudo apt-get update - sudo apt-get install -y pkg-config libxmu-dev libxi-dev libgl-dev libglu1-mesa-dev libsdl2-dev - - - name: Install CMake & Ninja - uses: lukka/get-cmake@latest - with: - cmakeVersion: 3.29.2 - - - uses: actions/checkout@v4 - with: - submodules: 'recursive' - - - name: sccache - uses: hendrikmuhs/ccache-action@v1.2 - with: - variant: sccache - key: ${{ github.job }}-${{ runner.os }} - max-size: 250M - - - name: vcpkg - uses: lukka/run-vcpkg@v11 - id: runvcpkg - with: - vcpkgJsonGlob: '**/source/vcpkg.json' - vcpkgConfigurationJsonGlob: '**/source/vcpkg-configuration.json' - - - name: Run CMake - uses: lukka/run-cmake@v10 - with: - cmakeListsTxtPath: '${{ github.workspace }}/source/CMakeLists.txt' - configurePreset: 'linux-release' - buildPreset: 'linux-release' - testPreset: 'linux-release' - - - name: Assemble Files - working-directory: ${{ github.workspace }} - run: scripts/ci/linux/assemble.sh - - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - with: - name: OpenStarbound-Linux - path: dist.tar - - - name: Upload Client Files - uses: actions/upload-artifact@v4 - with: - name: OpenStarbound-Linux-Client - path: client.tar - - - name: Upload Server Files - uses: actions/upload-artifact@v4 - with: - name: OpenStarbound-Linux-Server - path: server.tar \ No newline at end of file diff --git a/.github/workflows/build_macos.yml b/.github/workflows/build_macos.yml deleted file mode 100644 index 1cfd12c..0000000 --- a/.github/workflows/build_macos.yml +++ /dev/null @@ -1,97 +0,0 @@ -name: macOS - -on: - push: - branches: - - "*" - tags: - - "*" - - pull_request: - branches: - - "*" - -jobs: - build-intel: - name: OpenStarbound macOS x86_64 - runs-on: macos-13 - - steps: - - uses: actions/checkout@v4 - with: - submodules: 'recursive' - - - name: Install CMake & Ninja - uses: lukka/get-cmake@latest - with: - cmakeVersion: 3.29.0 - - - name: sccache - uses: hendrikmuhs/ccache-action@v1.2 - with: - variant: sccache - key: ${{ github.job }}-Intel-${{ runner.os }} - max-size: 250M - - - name: vcpkg - uses: lukka/run-vcpkg@v11 - id: runvcpkg - with: - vcpkgJsonGlob: '**/source/vcpkg.json' - vcpkgConfigurationJsonGlob: '**/source/vcpkg-configuration.json' - - - name: Run CMake - uses: lukka/run-cmake@v10 - with: - cmakeListsTxtPath: '${{ github.workspace }}/source/CMakeLists.txt' - configurePreset: 'macos-release' - buildPreset: 'macos-release' - testPreset: 'macos-release' - - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - with: - name: OpenStarbound-macOS-Intel - path: dist/* - - build-arm: - name: OpenStarbound macOS arm64 - runs-on: macos-14 - - steps: - - uses: actions/checkout@v4 - with: - submodules: 'recursive' - - - name: Install CMake & Ninja - uses: lukka/get-cmake@latest - with: - cmakeVersion: 3.29.2 - - - name: sccache - uses: hendrikmuhs/ccache-action@v1.2 - with: - variant: sccache - key: ${{ github.job }}-ARM-${{ runner.os }} - max-size: 250M - - - name: vcpkg - uses: lukka/run-vcpkg@v11 - id: runvcpkg - with: - vcpkgJsonGlob: '**/source/vcpkg.json' - vcpkgConfigurationJsonGlob: '**/source/vcpkg-configuration.json' - - - name: Run CMake - uses: lukka/run-cmake@v10 - with: - cmakeListsTxtPath: '${{ github.workspace }}/source/CMakeLists.txt' - configurePreset: 'macos-arm-release' - buildPreset: 'macos-arm-release' - testPreset: 'macos-arm-release' - - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - with: - name: OpenStarbound-macOS-Silicon - path: dist/* \ No newline at end of file diff --git a/.github/workflows/build_windows.yml b/.github/workflows/build_windows.yml deleted file mode 100644 index d3ee36b..0000000 --- a/.github/workflows/build_windows.yml +++ /dev/null @@ -1,89 +0,0 @@ -name: Windows - -on: - push: - branches: - - "*" - tags: - - "*" - - pull_request: - branches: - - "*" - -jobs: - build: - name: Build OpenStarbound Windows x64 - runs-on: windows-latest - - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - submodules: 'recursive' - - - name: Install CMake & Ninja - uses: lukka/get-cmake@latest - with: - cmakeVersion: 3.29.2 - - - name: sccache - uses: hendrikmuhs/ccache-action@v1.2 - with: - variant: sccache - key: ${{ github.job }}-${{ runner.os }} - max-size: 1000M - - - uses: ilammy/msvc-dev-cmd@v1 - - - name: vcpkg - uses: lukka/run-vcpkg@v11 - id: runvcpkg - with: - vcpkgJsonGlob: '**/source/vcpkg.json' - vcpkgConfigurationJsonGlob: '**/source/vcpkg-configuration.json' - - - name: Run CMake - uses: lukka/run-cmake@v10 - with: - cmakeListsTxtPath: '${{ github.workspace }}/source/CMakeLists.txt' - configurePreset: 'windows-release' - buildPreset: 'windows-release' - testPreset: 'windows-release' - - - name: Run Post-Build Task - working-directory: ${{ github.workspace }} - run: scripts\ci\windows\post_build.bat - - - name: Assemble Files - working-directory: ${{ github.workspace }} - run: scripts\ci\windows\assemble.bat - - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - with: - name: OpenStarbound-Windows-All-DevOnly - path: dist/* - - - name: Upload Client - uses: actions/upload-artifact@v4 - with: - name: OpenStarbound-Windows-Client - path: client_distribution/* - - - name: Upload Server - uses: actions/upload-artifact@v4 - with: - name: OpenStarbound-Windows-Server - path: server_distribution/* - - - name: Create Installer - working-directory: ${{ github.workspace }} - run: | - & "C:\Program Files (x86)\Inno Setup 6\iscc.exe" /Oinstaller scripts\inno\setup.iss - - - name: Upload Installer - uses: actions/upload-artifact@v4 - with: - name: OpenStarbound-Windows-Installer - path: installer/* diff --git a/source/base/StarAssets.cpp b/source/base/StarAssets.cpp index c47b71c..f81a4ee 100644 --- a/source/base/StarAssets.cpp +++ b/source/base/StarAssets.cpp @@ -68,7 +68,7 @@ static void validatePath(AssetPath const& components, bool canContainSubPath, bo throw AssetException::format("Path '{}' cannot contain directives", components); } -static void validatePath(StringView const& path, bool canContainSubPath, bool canContainDirectives) { +static void validatePath(StringView path, bool canContainSubPath, bool canContainDirectives) { std::string_view const& str = path.utf8(); size_t end = str.find_first_of(":?"); diff --git a/source/core/CMakeLists.txt b/source/core/CMakeLists.txt index fb31fca..bb8bd22 100644 --- a/source/core/CMakeLists.txt +++ b/source/core/CMakeLists.txt @@ -70,10 +70,12 @@ SET (star_core_HEADERS StarMultiArray.hpp StarMultiArrayInterpolator.hpp StarMultiTable.hpp + StarNetCompatibility.hpp StarNetElement.hpp StarNetElementBasicFields.hpp StarNetElementContainers.hpp StarNetElementDynamicGroup.hpp + StarNetElementExt.hpp StarNetElementFloatFields.hpp StarNetElementGroup.hpp StarNetElementSignal.hpp diff --git a/source/core/StarDataStream.cpp b/source/core/StarDataStream.cpp index 18456b6..1224f54 100644 --- a/source/core/StarDataStream.cpp +++ b/source/core/StarDataStream.cpp @@ -35,6 +35,13 @@ void DataStream::setStreamCompatibilityVersion(unsigned streamCompatibilityVersi m_streamCompatibilityVersion = streamCompatibilityVersion; } +void DataStream::setStreamCompatibilityVersion(NetCompatibilityRules const& rules) { + if (rules.isLegacy) + m_streamCompatibilityVersion = 1; + else + m_streamCompatibilityVersion = CurrentStreamVersion; +} + ByteArray DataStream::readBytes(size_t len) { ByteArray ba; ba.resize(len); diff --git a/source/core/StarDataStream.hpp b/source/core/StarDataStream.hpp index 02cb922..abcbff4 100644 --- a/source/core/StarDataStream.hpp +++ b/source/core/StarDataStream.hpp @@ -1,6 +1,7 @@ #pragma once #include "StarString.hpp" +#include "StarNetCompatibility.hpp" namespace Star { @@ -12,7 +13,7 @@ public: DataStream(); virtual ~DataStream() = default; - static unsigned const CurrentStreamVersion = 1; + static unsigned const CurrentStreamVersion = 2; // DataStream defaults to big-endian order for all primitive types ByteOrder byteOrder() const; @@ -27,7 +28,7 @@ public: // changed for compatibility with older versions of DataStream serialization. unsigned streamCompatibilityVersion() const; void setStreamCompatibilityVersion(unsigned streamCompatibilityVersion); - + void setStreamCompatibilityVersion(NetCompatibilityRules const& rules); // Do direct reads and writes virtual void readData(char* data, size_t len) = 0; virtual void writeData(char const* data, size_t len) = 0; diff --git a/source/core/StarDataStreamDevices.hpp b/source/core/StarDataStreamDevices.hpp index 3f34a72..4452592 100644 --- a/source/core/StarDataStreamDevices.hpp +++ b/source/core/StarDataStreamDevices.hpp @@ -126,8 +126,8 @@ private: class DataStreamExternalBuffer : public DataStream { public: DataStreamExternalBuffer(); - explicit DataStreamExternalBuffer(ByteArray const& byteArray); - explicit DataStreamExternalBuffer(DataStreamBuffer const& buffer); + DataStreamExternalBuffer(ByteArray const& byteArray); + DataStreamExternalBuffer(DataStreamBuffer const& buffer); DataStreamExternalBuffer(DataStreamExternalBuffer const& buffer) = default; DataStreamExternalBuffer(char const* externalData, size_t len); diff --git a/source/core/StarNetCompatibility.hpp b/source/core/StarNetCompatibility.hpp new file mode 100644 index 0000000..730546e --- /dev/null +++ b/source/core/StarNetCompatibility.hpp @@ -0,0 +1,41 @@ +#pragma once +#include "StarDataStream.hpp" + +namespace Star { + + +enum class NetCompatibilityFilter { + None = 0, + Old = 1, + New = 2 +}; + +struct NetCompatibilityRules { + NetCompatibilityRules() = default; + NetCompatibilityRules(uint64_t) = delete; + NetCompatibilityRules(bool legacy); + + bool checkFilter(NetCompatibilityFilter const& filter) const; + + bool isLegacy = false; +}; + +inline NetCompatibilityRules::NetCompatibilityRules(bool legacy) : isLegacy(legacy) {} + +inline bool NetCompatibilityRules::checkFilter(NetCompatibilityFilter const& filter) const { + if (filter == NetCompatibilityFilter::None) + return true; + else if (isLegacy) + return filter == NetCompatibilityFilter::Old; + else + return filter == NetCompatibilityFilter::New; +} + +template <> +struct hash { + size_t operator()(NetCompatibilityRules const& s) const { + return s.isLegacy; + } +}; + +} \ No newline at end of file diff --git a/source/core/StarNetElement.cpp b/source/core/StarNetElement.cpp index 914badd..343d45a 100644 --- a/source/core/StarNetElement.cpp +++ b/source/core/StarNetElement.cpp @@ -7,8 +7,8 @@ uint64_t NetElementVersion::current() const { return m_version; } -void NetElementVersion::increment() { - ++m_version; +uint64_t NetElementVersion::increment() { + return ++m_version; } void NetElement::enableNetInterpolation(float) {} diff --git a/source/core/StarNetElement.hpp b/source/core/StarNetElement.hpp index dd909b8..393dd3d 100644 --- a/source/core/StarNetElement.hpp +++ b/source/core/StarNetElement.hpp @@ -9,7 +9,7 @@ namespace Star { class NetElementVersion { public: uint64_t current() const; - void increment(); + uint64_t increment(); private: uint64_t m_version = 0; @@ -20,15 +20,15 @@ class NetElement { public: virtual ~NetElement() = default; - // A network of NetElements will have a shared monotinically increasing + // A network of NetElements will have a shared monotonically increasing // NetElementVersion. When elements are updated, they will mark the version // number at the time they are updated so that a delta can be constructed // that contains only changes since any past version. virtual void initNetVersion(NetElementVersion const* version = nullptr) = 0; // Full store / load of the entire element. - virtual void netStore(DataStream& ds) const = 0; - virtual void netLoad(DataStream& ds) = 0; + virtual void netStore(DataStream& ds, NetCompatibilityRules rules) const = 0; + virtual void netLoad(DataStream& ds, NetCompatibilityRules rules) = 0; // Enables interpolation mode. If interpolation mode is enabled, then // NetElements will delay presenting incoming delta data for the @@ -46,14 +46,32 @@ public: // the version at the time of the *last* call to writeDelta, + 1. If // fromVersion is 0, this will always write the full state. Should return // true if a delta was needed and was written to DataStream, false otherwise. - virtual bool writeNetDelta(DataStream& ds, uint64_t fromVersion) const = 0; + virtual bool writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules) const = 0; // Read a delta written by writeNetDelta. 'interpolationTime' is the time in // the future that data from this delta should be delayed and smoothed into, // if interpolation is enabled. - virtual void readNetDelta(DataStream& ds, float interpolationTime = 0.0) = 0; + virtual void readNetDelta(DataStream& ds, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) = 0; // When extrapolating, it is important to notify when a delta WOULD have been // received even if no deltas are produced, so no extrapolation takes place. virtual void blankNetDelta(float interpolationTime); + + NetCompatibilityFilter netCompatibilityFilter() const; + void setNetCompatibilityFilter(NetCompatibilityFilter netFilter); + bool checkWithRules(NetCompatibilityRules const& rules) const; +private: + NetCompatibilityFilter m_netCompatibilityFilter = NetCompatibilityFilter::None; }; +inline NetCompatibilityFilter NetElement::netCompatibilityFilter() const { + return m_netCompatibilityFilter; +} + +inline void NetElement::setNetCompatibilityFilter(NetCompatibilityFilter netFilter) { + m_netCompatibilityFilter = netFilter; +} + +inline bool NetElement::checkWithRules(NetCompatibilityRules const& rules) const { + return rules.checkFilter(m_netCompatibilityFilter); +} + } diff --git a/source/core/StarNetElementBasicFields.cpp b/source/core/StarNetElementBasicFields.cpp index bbb5c5b..618c4a6 100644 --- a/source/core/StarNetElementBasicFields.cpp +++ b/source/core/StarNetElementBasicFields.cpp @@ -49,8 +49,8 @@ void NetElementEvent::setIgnoreOccurrencesOnNetLoad(bool ignoreOccurrencesOnNetL m_ignoreOccurrencesOnNetLoad = ignoreOccurrencesOnNetLoad; } -void NetElementEvent::netLoad(DataStream& ds) { - NetElementUInt::netLoad(ds); +void NetElementEvent::netLoad(DataStream& ds, NetCompatibilityRules rules) { + NetElementUInt::netLoad(ds, rules); if (m_ignoreOccurrencesOnNetLoad) ignoreOccurrences(); } diff --git a/source/core/StarNetElementBasicFields.hpp b/source/core/StarNetElementBasicFields.hpp index 693c6c3..3b46cc0 100644 --- a/source/core/StarNetElementBasicFields.hpp +++ b/source/core/StarNetElementBasicFields.hpp @@ -38,11 +38,11 @@ public: void disableNetInterpolation() override; void tickNetInterpolation(float dt) override; - void netStore(DataStream& ds) const override; - void netLoad(DataStream& ds) override; + void netStore(DataStream& ds, NetCompatibilityRules rules = {}) const override; + void netLoad(DataStream& ds, NetCompatibilityRules rules) override; - bool writeNetDelta(DataStream& ds, uint64_t fromVersion) const override; - void readNetDelta(DataStream& ds, float interpolationTime = 0.0f) override; + bool writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules = {}) const override; + void readNetDelta(DataStream& ds, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; protected: virtual void readData(DataStream& ds, T& t) const = 0; @@ -107,7 +107,7 @@ public: void ignoreOccurrences(); void setIgnoreOccurrencesOnNetLoad(bool ignoreOccurrencesOnNetLoad); - void netLoad(DataStream& ds) override; + void netLoad(DataStream& ds, NetCompatibilityRules rules) override; protected: void updated() override; @@ -211,7 +211,8 @@ void NetElementBasicField::tickNetInterpolation(float dt) { } template -void NetElementBasicField::netStore(DataStream& ds) const { +void NetElementBasicField::netStore(DataStream& ds, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return; if (m_pendingInterpolatedValues && !m_pendingInterpolatedValues->empty()) writeData(ds, m_pendingInterpolatedValues->last().second); else @@ -219,7 +220,8 @@ void NetElementBasicField::netStore(DataStream& ds) const { } template -void NetElementBasicField::netLoad(DataStream& ds) { +void NetElementBasicField::netLoad(DataStream& ds, NetCompatibilityRules rules) { + if (!checkWithRules(rules)) return; readData(ds, m_value); m_latestUpdateVersion = m_netVersion ? m_netVersion->current() : 0; updated(); @@ -228,7 +230,8 @@ void NetElementBasicField::netLoad(DataStream& ds) { } template -bool NetElementBasicField::writeNetDelta(DataStream& ds, uint64_t fromVersion) const { +bool NetElementBasicField::writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return false; if (m_latestUpdateVersion < fromVersion) return false; @@ -236,11 +239,13 @@ bool NetElementBasicField::writeNetDelta(DataStream& ds, uint64_t fromVersion writeData(ds, m_pendingInterpolatedValues->last().second); else writeData(ds, m_value); + return true; } template -void NetElementBasicField::readNetDelta(DataStream& ds, float interpolationTime) { +void NetElementBasicField::readNetDelta(DataStream& ds, float interpolationTime, NetCompatibilityRules rules) { + if (!checkWithRules(rules)) return; T t; readData(ds, t); m_latestUpdateVersion = m_netVersion ? m_netVersion->current() : 0; diff --git a/source/core/StarNetElementContainers.hpp b/source/core/StarNetElementContainers.hpp index 62cce86..2e16b30 100644 --- a/source/core/StarNetElementContainers.hpp +++ b/source/core/StarNetElementContainers.hpp @@ -26,11 +26,12 @@ public: void disableNetInterpolation() override; void tickNetInterpolation(float dt) override; - void netStore(DataStream& ds) const override; - void netLoad(DataStream& ds) override; + void netStore(DataStream& ds, NetCompatibilityRules rules = {}) const override; + void netLoad(DataStream& ds, NetCompatibilityRules rules) override; - bool writeNetDelta(DataStream& ds, uint64_t fromVersion) const override; - void readNetDelta(DataStream& ds, float interpolationTime = 0.0f) override; + bool shouldWriteNetDelta(uint64_t fromVersion, NetCompatibilityRules rules = {}) const; + bool writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules = {}) const override; + void readNetDelta(DataStream& ds, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; mapped_type const& get(key_type const& key) const; mapped_type const* ptr(key_type const& key) const; @@ -77,6 +78,8 @@ public: template void setContents(MapType const& values); + uint64_t changeDataLastVersion() const; + private: // If a delta is written from further back than this many steps, the delta // will fall back to a full serialization of the entire state. @@ -152,7 +155,8 @@ void NetElementMapWrapper::tickNetInterpolation(float dt) { } template -void NetElementMapWrapper::netStore(DataStream& ds) const { +void NetElementMapWrapper::netStore(DataStream& ds, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return; ds.writeVlqU(BaseMap::size() + m_pendingChangeData.size()); for (auto const& pair : *this) writeChange(ds, SetChange{pair.first, pair.second}); @@ -162,7 +166,8 @@ void NetElementMapWrapper::netStore(DataStream& ds) const { } template -void NetElementMapWrapper::netLoad(DataStream& ds) { +void NetElementMapWrapper::netLoad(DataStream& ds, NetCompatibilityRules rules) { + if (!checkWithRules(rules)) return; m_changeData.clear(); m_changeDataLastVersion = m_netVersion ? m_netVersion->current() : 0; m_pendingChangeData.clear(); @@ -181,13 +186,27 @@ void NetElementMapWrapper::netLoad(DataStream& ds) { } template -bool NetElementMapWrapper::writeNetDelta(DataStream& ds, uint64_t fromVersion) const { +bool NetElementMapWrapper::shouldWriteNetDelta(uint64_t fromVersion, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return false; + if (fromVersion < m_changeDataLastVersion) + return true; + + for (auto const& p : m_changeData) + if (p.first >= fromVersion) + return true; + + return false; +} + +template +bool NetElementMapWrapper::writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return false; bool deltaWritten = false; if (fromVersion < m_changeDataLastVersion) { deltaWritten = true; ds.writeVlqU(1); - netStore(ds); + netStore(ds, rules); } else { for (auto const& p : m_changeData) { @@ -206,13 +225,14 @@ bool NetElementMapWrapper::writeNetDelta(DataStream& ds, uint64_t fromV } template -void NetElementMapWrapper::readNetDelta(DataStream& ds, float interpolationTime) { +void NetElementMapWrapper::readNetDelta(DataStream& ds, float interpolationTime, NetCompatibilityRules rules) { + if (!checkWithRules(rules)) return; while (true) { uint64_t code = ds.readVlqU(); if (code == 0) { break; } else if (code == 1) { - netLoad(ds); + netLoad(ds, rules); } else if (code == 2) { auto change = readChange(ds); addChangeData(change); @@ -381,6 +401,11 @@ void NetElementMapWrapper::setContents(MapType const& values) { reset(BaseMap::from(values)); } +template +uint64_t NetElementMapWrapper::changeDataLastVersion() const { + return m_changeDataLastVersion; +} + template void NetElementMapWrapper::writeChange(DataStream& ds, ElementChange const& change) { if (auto sc = change.template ptr()) { diff --git a/source/core/StarNetElementDynamicGroup.hpp b/source/core/StarNetElementDynamicGroup.hpp index 4f3a2d3..dbd0c12 100644 --- a/source/core/StarNetElementDynamicGroup.hpp +++ b/source/core/StarNetElementDynamicGroup.hpp @@ -45,11 +45,11 @@ public: void disableNetInterpolation() override; void tickNetInterpolation(float dt) override; - void netStore(DataStream& ds) const override; - void netLoad(DataStream& ds) override; + void netStore(DataStream& ds, NetCompatibilityRules rules = {}) const override; + void netLoad(DataStream& ds, NetCompatibilityRules rules) override; - bool writeNetDelta(DataStream& ds, uint64_t fromVersion) const override; - void readNetDelta(DataStream& ds, float interpolationTime = 0.0f) override; + bool writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules = {}) const override; + void readNetDelta(DataStream& ds, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; void blankNetDelta(float interpolationTime = 0.0f) override; private: @@ -89,7 +89,7 @@ template auto NetElementDynamicGroup::addNetElement(ElementPtr element) -> ElementId { readyElement(element); DataStreamBuffer storeBuffer; - element->netStore(storeBuffer); + element->netStore(storeBuffer, {}); auto id = m_idMap.add(std::move(element)); addChangeData(ElementAddition(id, storeBuffer.takeData())); @@ -134,7 +134,7 @@ void NetElementDynamicGroup::initNetVersion(NetElementVersion const* ve for (auto& pair : m_idMap) { pair.second->initNetVersion(m_netVersion); DataStreamBuffer storeBuffer; - pair.second->netStore(storeBuffer); + pair.second->netStore(storeBuffer, {}); addChangeData(ElementAddition(pair.first, storeBuffer.takeData())); } } @@ -162,19 +162,22 @@ void NetElementDynamicGroup::tickNetInterpolation(float dt) { } template -void NetElementDynamicGroup::netStore(DataStream& ds) const { +void NetElementDynamicGroup::netStore(DataStream& ds, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return; ds.writeVlqU(m_idMap.size()); + m_buffer.setStreamCompatibilityVersion(rules); for (auto& pair : m_idMap) { ds.writeVlqU(pair.first); - pair.second->netStore(m_buffer); + pair.second->netStore(m_buffer, rules); ds.write(m_buffer.data()); m_buffer.clear(); } } template -void NetElementDynamicGroup::netLoad(DataStream& ds) { +void NetElementDynamicGroup::netLoad(DataStream& ds, NetCompatibilityRules rules) { + if (!checkWithRules(rules)) return; m_changeData.clear(); m_changeDataLastVersion = m_netVersion ? m_netVersion->current() : 0; m_idMap.clear(); @@ -188,7 +191,7 @@ void NetElementDynamicGroup::netLoad(DataStream& ds) { DataStreamBuffer storeBuffer(ds.read()); ElementPtr element = make_shared(); - element->netLoad(storeBuffer); + element->netLoad(storeBuffer, rules); readyElement(element); m_idMap.add(id, std::move(element)); @@ -197,10 +200,11 @@ void NetElementDynamicGroup::netLoad(DataStream& ds) { } template -bool NetElementDynamicGroup::writeNetDelta(DataStream& ds, uint64_t fromVersion) const { +bool NetElementDynamicGroup::writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return false; if (fromVersion < m_changeDataLastVersion) { ds.write(true); - netStore(ds); + netStore(ds, rules); return true; } else { @@ -220,8 +224,9 @@ bool NetElementDynamicGroup::writeNetDelta(DataStream& ds, uint64_t fro } } + m_buffer.setStreamCompatibilityVersion(rules); for (auto& p : m_idMap) { - if (p.second->writeNetDelta(m_buffer, fromVersion)) { + if (p.second->writeNetDelta(m_buffer, fromVersion, rules)) { willWrite(); ds.writeVlqU(p.first + 1); ds.writeBytes(m_buffer.data()); @@ -237,10 +242,11 @@ bool NetElementDynamicGroup::writeNetDelta(DataStream& ds, uint64_t fro } template -void NetElementDynamicGroup::readNetDelta(DataStream& ds, float interpolationTime) { +void NetElementDynamicGroup::readNetDelta(DataStream& ds, float interpolationTime, NetCompatibilityRules rules) { + if (!checkWithRules(rules)) return; bool isFull = ds.read(); if (isFull) { - netLoad(ds); + netLoad(ds, rules); } else { while (true) { uint64_t code = ds.readVlqU(); @@ -256,7 +262,7 @@ void NetElementDynamicGroup::readNetDelta(DataStream& ds, float interpo } else if (auto addition = changeUpdate.template ptr()) { ElementPtr element = make_shared(); DataStreamBuffer storeBuffer(std::move(get<1>(*addition))); - element->netLoad(storeBuffer); + element->netLoad(storeBuffer, rules); readyElement(element); m_idMap.add(get<0>(*addition), std::move(element)); } else if (auto removal = changeUpdate.template ptr()) { @@ -265,7 +271,7 @@ void NetElementDynamicGroup::readNetDelta(DataStream& ds, float interpo } else { ElementId elementId = code - 1; auto const& element = m_idMap.get(elementId); - element->readNetDelta(ds, interpolationTime); + element->readNetDelta(ds, interpolationTime, rules); if (m_interpolationEnabled) m_receivedDeltaIds.add(elementId); } diff --git a/source/core/StarNetElementExt.hpp b/source/core/StarNetElementExt.hpp new file mode 100644 index 0000000..50802fe --- /dev/null +++ b/source/core/StarNetElementExt.hpp @@ -0,0 +1,85 @@ +#pragma once + +#include "StarNetElement.hpp" + +namespace Star { + +template +class NetElementOverride : public BaseNetElement { +public: + void netStore(DataStream& ds, NetCompatibilityRules rules = {}) const override; + void netLoad(DataStream& ds, NetCompatibilityRules rules) override; + + bool writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules = {}) const override; + void readNetDelta(DataStream& ds, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; + + typedef std::function NetStorer; + typedef std::function NetLoader; + typedef std::function NetDeltaWriter; + typedef std::function NetDeltaReader; + + void setNetStorer(NetStorer); + void setNetLoader(NetLoader); + void setNetDeltaWriter(NetDeltaWriter); + void setNetDeltaReader(NetDeltaReader); + void setOverrides(NetStorer netStorer, NetLoader netLoader, + NetDeltaWriter netDeltaWriter, NetDeltaReader netDeltaReader); + +private: + NetStorer m_netStorer; + NetLoader m_netLoader; + + NetDeltaWriter m_netDeltaWriter; + NetDeltaReader m_netDeltaReader; +}; + +template +void NetElementOverride::netStore(DataStream& ds, NetCompatibilityRules rules) const { + if (m_netStorer) + m_netStorer(ds, rules); + else + BaseNetElement::netStore(ds, rules); +} + +template +void NetElementOverride::netLoad(DataStream& ds, NetCompatibilityRules rules) { + if (m_netLoader) + m_netLoader(ds, rules); + else + BaseNetElement::netLoad(ds, rules); +} + +template +bool NetElementOverride::writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules) const { + if (m_netDeltaWriter) + return m_netDeltaWriter(ds, fromVersion, rules); + else + return BaseNetElement::writeNetDelta(ds, fromVersion, rules); +} + +template +void NetElementOverride::readNetDelta(DataStream& ds, float interpolationTime, NetCompatibilityRules rules) { + if (m_netDeltaReader) + m_netDeltaReader(ds, interpolationTime, rules); + else + BaseNetElement::readNetDelta(ds, interpolationTime, rules); +} + +template +inline void NetElementOverride::setNetStorer(NetStorer f) { m_netStorer = std::move(f); } +template +inline void NetElementOverride::setNetLoader(NetLoader f) { m_netLoader = std::move(f); } +template +inline void NetElementOverride::setNetDeltaWriter(NetDeltaWriter f) { m_netDeltaWriter = std::move(f); } +template +inline void NetElementOverride::setNetDeltaReader(NetDeltaReader f) { m_netDeltaReader = std::move(f); } + +template +inline void NetElementOverride::setOverrides(NetStorer netStorer, NetLoader netLoader, NetDeltaWriter netDeltaWriter, NetDeltaReader netDeltaReader) { + m_netStorer = std::move(netStorer); + m_netLoader = std::move(netLoader); + m_netDeltaWriter = std::move(netDeltaWriter); + m_netDeltaReader = std::move(netDeltaReader); +} + +} \ No newline at end of file diff --git a/source/core/StarNetElementFloatFields.hpp b/source/core/StarNetElementFloatFields.hpp index 57f74a9..6c8fbcf 100644 --- a/source/core/StarNetElementFloatFields.hpp +++ b/source/core/StarNetElementFloatFields.hpp @@ -36,11 +36,11 @@ public: void disableNetInterpolation() override; void tickNetInterpolation(float dt) override; - void netStore(DataStream& ds) const override; - void netLoad(DataStream& ds) override; + void netStore(DataStream& ds, NetCompatibilityRules rules = {}) const override; + void netLoad(DataStream& ds, NetCompatibilityRules rules) override; - bool writeNetDelta(DataStream& ds, uint64_t fromVersion) const override; - void readNetDelta(DataStream& ds, float interpolationTime = 0.0f) override; + bool writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules = {}) const override; + void readNetDelta(DataStream& ds, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; void blankNetDelta(float interpolationTime = 0.0f) override; private: @@ -131,7 +131,8 @@ void NetElementFloating::tickNetInterpolation(float dt) { } template -void NetElementFloating::netStore(DataStream& ds) const { +void NetElementFloating::netStore(DataStream& ds, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return; if (m_interpolationDataPoints) writeValue(ds, m_interpolationDataPoints->last().second); else @@ -139,7 +140,8 @@ void NetElementFloating::netStore(DataStream& ds) const { } template -void NetElementFloating::netLoad(DataStream& ds) { +void NetElementFloating::netLoad(DataStream& ds, NetCompatibilityRules rules) { + if (!checkWithRules(rules)) return; m_value = readValue(ds); m_latestUpdateVersion = m_netVersion ? m_netVersion->current() : 0; if (m_interpolationDataPoints) { @@ -149,7 +151,8 @@ void NetElementFloating::netLoad(DataStream& ds) { } template -bool NetElementFloating::writeNetDelta(DataStream& ds, uint64_t fromVersion) const { +bool NetElementFloating::writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return false; if (m_latestUpdateVersion < fromVersion) return false; @@ -162,7 +165,7 @@ bool NetElementFloating::writeNetDelta(DataStream& ds, uint64_t fromVersion) } template -void NetElementFloating::readNetDelta(DataStream& ds, float interpolationTime) { +void NetElementFloating::readNetDelta(DataStream& ds, float interpolationTime, NetCompatibilityRules rules) { T t = readValue(ds); m_latestUpdateVersion = m_netVersion ? m_netVersion->current() : 0; diff --git a/source/core/StarNetElementGroup.cpp b/source/core/StarNetElementGroup.cpp index 249c978..6626e2b 100644 --- a/source/core/StarNetElementGroup.cpp +++ b/source/core/StarNetElementGroup.cpp @@ -21,14 +21,18 @@ void NetElementGroup::initNetVersion(NetElementVersion const* version) { p.first->initNetVersion(m_version); } -void NetElementGroup::netStore(DataStream& ds) const { +void NetElementGroup::netStore(DataStream& ds, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return; for (auto& p : m_elements) - p.first->netStore(ds); + if (p.first->checkWithRules(rules)) + p.first->netStore(ds, rules); } -void NetElementGroup::netLoad(DataStream& ds) { +void NetElementGroup::netLoad(DataStream& ds, NetCompatibilityRules rules) { + if (!checkWithRules(rules)) return; for (auto& p : m_elements) - p.first->netLoad(ds); + if (p.first->checkWithRules(rules)) + p.first->netLoad(ds, rules); } void NetElementGroup::enableNetInterpolation(float extrapolationHint) { @@ -56,17 +60,23 @@ void NetElementGroup::tickNetInterpolation(float dt) { } } -bool NetElementGroup::writeNetDelta(DataStream& ds, uint64_t fromStep) const { +bool NetElementGroup::writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return false; if (m_elements.size() == 0) { return false; } else if (m_elements.size() == 1) { - return m_elements[0].first->writeNetDelta(ds, fromStep); + return m_elements[0].first->writeNetDelta(ds, fromVersion, rules); } else { bool deltaWritten = false; - for (uint64_t i = 0; i < m_elements.size(); ++i) { - if (m_elements[i].first->writeNetDelta(m_buffer, fromStep)) { + uint64_t i = 0; + m_buffer.setStreamCompatibilityVersion(rules); + for (auto& element : m_elements) { + if (!element.first->checkWithRules(rules)) + continue; + ++i; + if (element.first->writeNetDelta(m_buffer, fromVersion, rules)) { deltaWritten = true; - ds.writeVlqU(i + 1); + ds.writeVlqU(i); ds.writeBytes(m_buffer.data()); m_buffer.clear(); } @@ -77,23 +87,28 @@ bool NetElementGroup::writeNetDelta(DataStream& ds, uint64_t fromStep) const { } } -void NetElementGroup::readNetDelta(DataStream& ds, float interpolationTime) { +void NetElementGroup::readNetDelta(DataStream& ds, float interpolationTime, NetCompatibilityRules rules) { + if (!checkWithRules(rules)) return; if (m_elements.size() == 0) { throw IOException("readNetDelta called on empty NetElementGroup"); } else if (m_elements.size() == 1) { - m_elements[0].first->readNetDelta(ds, interpolationTime); + m_elements[0].first->readNetDelta(ds, interpolationTime, rules); } else { uint64_t readIndex = ds.readVlqU(); - for (uint64_t i = 0; i < m_elements.size(); ++i) { + uint64_t i = 0; + for (auto& element : m_elements) { + if (!element.first->checkWithRules(rules)) + continue; if (readIndex == 0 || readIndex - 1 > i) { if (m_interpolationEnabled) m_elements[i].first->blankNetDelta(interpolationTime); } else if (readIndex - 1 == i) { - m_elements[i].first->readNetDelta(ds, interpolationTime); + m_elements[i].first->readNetDelta(ds, interpolationTime, rules); readIndex = ds.readVlqU(); } else { throw IOException("group indexes out of order in NetElementGroup::readNetDelta"); } + ++i; } } } diff --git a/source/core/StarNetElementGroup.hpp b/source/core/StarNetElementGroup.hpp index fd1bf58..1904a33 100644 --- a/source/core/StarNetElementGroup.hpp +++ b/source/core/StarNetElementGroup.hpp @@ -24,15 +24,15 @@ public: void initNetVersion(NetElementVersion const* version = nullptr) override; - void netStore(DataStream& ds) const override; - void netLoad(DataStream& ds) override; + void netStore(DataStream& ds, NetCompatibilityRules rules = {}) const override; + void netLoad(DataStream& ds, NetCompatibilityRules rules) override; void enableNetInterpolation(float extrapolationHint = 0.0f) override; void disableNetInterpolation() override; void tickNetInterpolation(float dt) override; - bool writeNetDelta(DataStream& ds, uint64_t fromVersion) const override; - void readNetDelta(DataStream& ds, float interpolationTime = 0.0f) override; + bool writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules = {}) const override; + void readNetDelta(DataStream& ds, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; void blankNetDelta(float interpolationTime) override; NetElementVersion const* netVersion() const; diff --git a/source/core/StarNetElementSignal.hpp b/source/core/StarNetElementSignal.hpp index 9faa127..61a108d 100644 --- a/source/core/StarNetElementSignal.hpp +++ b/source/core/StarNetElementSignal.hpp @@ -16,15 +16,15 @@ public: void initNetVersion(NetElementVersion const* version = nullptr) override; - void netStore(DataStream& ds) const override; - void netLoad(DataStream& ds) override; + void netStore(DataStream& ds, NetCompatibilityRules rules = {}) const override; + void netLoad(DataStream& ds, NetCompatibilityRules rules) override; void enableNetInterpolation(float extrapolationHint = 0.0f) override; void disableNetInterpolation() override; void tickNetInterpolation(float dt) override; - bool writeNetDelta(DataStream& ds, uint64_t fromVersion) const override; - void readNetDelta(DataStream& ds, float interpolationTime = 0.0) override; + bool writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules = {}) const override; + void readNetDelta(DataStream& ds, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; void send(Signal signal); List receive(); @@ -55,10 +55,10 @@ void NetElementSignal::initNetVersion(NetElementVersion const* version) } template -void NetElementSignal::netStore(DataStream&) const {} +void NetElementSignal::netStore(DataStream&, NetCompatibilityRules) const {} template -void NetElementSignal::netLoad(DataStream&) { +void NetElementSignal::netLoad(DataStream&, NetCompatibilityRules) { } template @@ -83,7 +83,8 @@ void NetElementSignal::tickNetInterpolation(float dt) { } template -bool NetElementSignal::writeNetDelta(DataStream& ds, uint64_t fromVersion) const { +bool NetElementSignal::writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return false; size_t numToWrite = 0; for (auto const& p : m_signals) { if (p.version >= fromVersion) @@ -103,7 +104,8 @@ bool NetElementSignal::writeNetDelta(DataStream& ds, uint64_t fromVersio } template -void NetElementSignal::readNetDelta(DataStream& ds, float interpolationTime) { +void NetElementSignal::readNetDelta(DataStream& ds, float interpolationTime, NetCompatibilityRules rules) { + if (!checkWithRules(rules)) return; size_t numToRead = ds.readVlqU(); for (size_t i = 0; i < numToRead; ++i) { Signal s; diff --git a/source/core/StarNetElementSyncGroup.cpp b/source/core/StarNetElementSyncGroup.cpp index ac8da92..cd98638 100644 --- a/source/core/StarNetElementSyncGroup.cpp +++ b/source/core/StarNetElementSyncGroup.cpp @@ -26,23 +26,27 @@ void NetElementSyncGroup::tickNetInterpolation(float dt) { } } -void NetElementSyncGroup::netStore(DataStream& ds) const { +void NetElementSyncGroup::netStore(DataStream& ds, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return; const_cast(this)->netElementsNeedStore(); - return NetElementGroup::netStore(ds); + return NetElementGroup::netStore(ds, rules); } -void NetElementSyncGroup::netLoad(DataStream& ds) { - NetElementGroup::netLoad(ds); +void NetElementSyncGroup::netLoad(DataStream& ds, NetCompatibilityRules rules) { + if (!checkWithRules(rules)) return; + NetElementGroup::netLoad(ds, rules); netElementsNeedLoad(true); } -bool NetElementSyncGroup::writeNetDelta(DataStream& ds, uint64_t fromVersion) const { +bool NetElementSyncGroup::writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return false; const_cast(this)->netElementsNeedStore(); - return NetElementGroup::writeNetDelta(ds, fromVersion); + return NetElementGroup::writeNetDelta(ds, fromVersion, rules); } -void NetElementSyncGroup::readNetDelta(DataStream& ds, float interpolationTime) { - NetElementGroup::readNetDelta(ds, interpolationTime); +void NetElementSyncGroup::readNetDelta(DataStream& ds, float interpolationTime, NetCompatibilityRules rules) { + if (!checkWithRules(rules)) return; + NetElementGroup::readNetDelta(ds, interpolationTime, rules); m_hasRecentChanges = true; m_recentDeltaTime = interpolationTime; diff --git a/source/core/StarNetElementSyncGroup.hpp b/source/core/StarNetElementSyncGroup.hpp index b01200b..30dafe8 100644 --- a/source/core/StarNetElementSyncGroup.hpp +++ b/source/core/StarNetElementSyncGroup.hpp @@ -13,11 +13,11 @@ public: void disableNetInterpolation() override; void tickNetInterpolation(float dt) override; - void netStore(DataStream& ds) const override; - void netLoad(DataStream& ds) override; + void netStore(DataStream& ds, NetCompatibilityRules rules = {}) const override; + void netLoad(DataStream& ds, NetCompatibilityRules rules) override; - bool writeNetDelta(DataStream& ds, uint64_t fromStep) const override; - void readNetDelta(DataStream& ds, float interpolationTime = 0.0f) override; + bool writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules = {}) const override; + void readNetDelta(DataStream& ds, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; void blankNetDelta(float interpolationTime = 0.0f) override; protected: diff --git a/source/core/StarNetElementTop.hpp b/source/core/StarNetElementTop.hpp index 454b34f..cf3cfb4 100644 --- a/source/core/StarNetElementTop.hpp +++ b/source/core/StarNetElementTop.hpp @@ -1,5 +1,4 @@ -#ifndef STAR_NET_ELEMENT_TOP_HPP -#define STAR_NET_ELEMENT_TOP_HPP +#pragma once #include "StarNetElement.hpp" @@ -12,10 +11,11 @@ class NetElementTop : public BaseNetElement { public: NetElementTop(); - // Returns the state update, combined with the version code that should be - // passed to the next call to writeState. If 'fromVersion' is 0, then this - // is a full write for an initial read of a slave NetElementTop. - pair writeNetState(uint64_t fromVersion = 0); + // Writes the state update to the given DataStream then returns the version + // code that should be passed to the next call to writeState. If + // 'fromVersion' is 0, then this is a full write for an initial read of a + // slave NetElementTop. + pair writeNetState(uint64_t fromVersion = 0, NetCompatibilityRules rules = {}); // Reads a state produced by a call to writeState, optionally with the // interpolation delay time for the data contained in this state update. If // the state is a full update rather than a delta, the interoplation delay @@ -23,7 +23,7 @@ public: // readState, *unless* extrapolation is enabled. If extrapolation is // enabled, reading a blank update calls 'blankNetDelta' which is necessary // to not improperly extrapolate past the end of incoming deltas. - void readNetState(ByteArray data, float interpolationTime = 0.0); + void readNetState(ByteArray data, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}); private: using BaseNetElement::initNetVersion; @@ -32,6 +32,7 @@ private: using BaseNetElement::writeNetDelta; using BaseNetElement::readNetDelta; using BaseNetElement::blankNetDelta; + using BaseNetElement::checkWithRules; NetElementVersion m_netVersion; }; @@ -42,41 +43,34 @@ NetElementTop::NetElementTop() { } template -pair NetElementTop::writeNetState(uint64_t fromVersion) { +pair NetElementTop::writeNetState(uint64_t fromVersion, NetCompatibilityRules rules) { + DataStreamBuffer ds; + ds.setStreamCompatibilityVersion(rules); if (fromVersion == 0) { - DataStreamBuffer ds; ds.write(true); - BaseNetElement::netStore(ds); - m_netVersion.increment(); - return {ds.takeData(), m_netVersion.current()}; - + BaseNetElement::netStore(ds, rules); + return {ds.takeData(), m_netVersion.increment()}; } else { - DataStreamBuffer ds; ds.write(false); - if (!BaseNetElement::writeNetDelta(ds, fromVersion)) { + if (!BaseNetElement::writeNetDelta(ds, fromVersion, rules)) return {ByteArray(), m_netVersion.current()}; - } else { - m_netVersion.increment(); - return {ds.takeData(), m_netVersion.current()}; - } + else + return {ds.takeData(), m_netVersion.increment()}; } } template -void NetElementTop::readNetState(ByteArray data, float interpolationTime) { +void NetElementTop::readNetState(ByteArray data, float interpolationTime, NetCompatibilityRules rules) { if (data.empty()) { BaseNetElement::blankNetDelta(interpolationTime); - } else { DataStreamBuffer ds(std::move(data)); - + ds.setStreamCompatibilityVersion(rules); if (ds.read()) - BaseNetElement::netLoad(ds); + BaseNetElement::netLoad(ds, rules); else - BaseNetElement::readNetDelta(ds, interpolationTime); + BaseNetElement::readNetDelta(ds, interpolationTime, rules); } } -} - -#endif +} \ No newline at end of file diff --git a/source/frontend/StarTeamBar.hpp b/source/frontend/StarTeamBar.hpp index ca50452..2ca40d6 100644 --- a/source/frontend/StarTeamBar.hpp +++ b/source/frontend/StarTeamBar.hpp @@ -1,5 +1,4 @@ -#ifndef STAR_TEAMBAR_HPP -#define STAR_TEAMBAR_HPP +#pragma once #include "StarPane.hpp" #include "StarUuid.hpp" @@ -113,6 +112,4 @@ private: friend class TeamMemberMenu; }; -} - -#endif +} \ No newline at end of file diff --git a/source/game/StarClientContext.cpp b/source/game/StarClientContext.cpp index a91c40e..3061368 100644 --- a/source/game/StarClientContext.cpp +++ b/source/game/StarClientContext.cpp @@ -77,11 +77,12 @@ ShipUpgrades ClientContext::shipUpgrades() const { return m_shipUpgrades.get(); } -void ClientContext::readUpdate(ByteArray data) { +void ClientContext::readUpdate(ByteArray data, NetCompatibilityRules rules) { if (data.empty()) return; DataStreamBuffer ds(std::move(data)); + ds.setStreamCompatibilityVersion(rules); m_rpc->receive(ds.read()); @@ -89,10 +90,10 @@ void ClientContext::readUpdate(ByteArray data) { if (!shipUpdates.empty()) m_newShipUpdates.merge(DataStreamBuffer::deserialize(std::move(shipUpdates)), true); - m_netGroup.readNetState(ds.read()); + m_netGroup.readNetState(ds.read(), 0.0f, rules); } -ByteArray ClientContext::writeUpdate() { +ByteArray ClientContext::writeUpdate(NetCompatibilityRules rules) { return m_rpc->send(); } @@ -104,4 +105,12 @@ ConnectionId ClientContext::connectionId() const { return m_connectionId; } +void ClientContext::setNetCompatibilityRules(NetCompatibilityRules netCompatibilityRules) { + m_netCompatibilityRules = netCompatibilityRules; +} + +NetCompatibilityRules ClientContext::netCompatibilityRules() const { + return m_netCompatibilityRules; +} + } diff --git a/source/game/StarClientContext.hpp b/source/game/StarClientContext.hpp index 5cdd727..9c08d32 100644 --- a/source/game/StarClientContext.hpp +++ b/source/game/StarClientContext.hpp @@ -40,16 +40,20 @@ public: WorldChunks newShipUpdates(); ShipUpgrades shipUpgrades() const; - void readUpdate(ByteArray data); - ByteArray writeUpdate(); + void readUpdate(ByteArray data, NetCompatibilityRules rules); + ByteArray writeUpdate(NetCompatibilityRules rules); void setConnectionId(ConnectionId connectionId); ConnectionId connectionId() const; + void setNetCompatibilityRules(NetCompatibilityRules netCompatibilityRules); + NetCompatibilityRules netCompatibilityRules() const; + private: Uuid m_serverUuid; Uuid m_playerUuid; ConnectionId m_connectionId = 0; + NetCompatibilityRules m_netCompatibilityRules; JsonRpcPtr m_rpc; diff --git a/source/game/StarEntityFactory.cpp b/source/game/StarEntityFactory.cpp index 333dec1..0202ea7 100644 --- a/source/game/StarEntityFactory.cpp +++ b/source/game/StarEntityFactory.cpp @@ -40,57 +40,57 @@ EntityFactory::EntityFactory() { m_versioningDatabase = root.versioningDatabase(); } -ByteArray EntityFactory::netStoreEntity(EntityPtr const& entity) const { +ByteArray EntityFactory::netStoreEntity(EntityPtr const& entity, NetCompatibilityRules rules) const { RecursiveMutexLocker locker(m_mutex); if (auto player = as(entity)) { - return player->netStore(); + return player->netStore(rules); } else if (auto monster = as(entity)) { - return monster->netStore(); + return monster->netStore(rules); } else if (auto object = as(entity)) { - return object->netStore(); + return object->netStore(rules); } else if (auto plant = as(entity)) { - return plant->netStore(); + return plant->netStore(rules); } else if (auto plantDrop = as(entity)) { - return plantDrop->netStore(); + return plantDrop->netStore(rules); } else if (auto projectile = as(entity)) { - return projectile->netStore(); + return projectile->netStore(rules); } else if (auto itemDrop = as(entity)) { - return itemDrop->netStore(); + return itemDrop->netStore(rules); } else if (auto npc = as(entity)) { - return npc->netStore(); + return npc->netStore(rules); } else if (auto stagehand = as(entity)) { - return stagehand->netStore(); + return stagehand->netStore(rules); } else if (auto vehicle = as(entity)) { - return m_vehicleDatabase->netStore(vehicle); + return m_vehicleDatabase->netStore(vehicle, rules); } else { throw EntityFactoryException::format("Don't know how to make net store for entity type '{}'", EntityTypeNames.getRight(entity->entityType())); } } -EntityPtr EntityFactory::netLoadEntity(EntityType type, ByteArray const& netStore) const { +EntityPtr EntityFactory::netLoadEntity(EntityType type, ByteArray const& netStore, NetCompatibilityRules rules) const { RecursiveMutexLocker locker(m_mutex); if (type == EntityType::Player) { - return m_playerFactory->netLoadPlayer(netStore); + return m_playerFactory->netLoadPlayer(netStore, rules); } else if (type == EntityType::Monster) { - return m_monsterDatabase->netLoadMonster(netStore); + return m_monsterDatabase->netLoadMonster(netStore, rules); } else if (type == EntityType::Object) { - return m_objectDatabase->netLoadObject(netStore); + return m_objectDatabase->netLoadObject(netStore, rules); } else if (type == EntityType::Plant) { - return make_shared(netStore); + return make_shared(netStore, rules); } else if (type == EntityType::PlantDrop) { - return make_shared(netStore); + return make_shared(netStore, rules); } else if (type == EntityType::Projectile) { - return m_projectileDatabase->netLoadProjectile(netStore); + return m_projectileDatabase->netLoadProjectile(netStore, rules); } else if (type == EntityType::ItemDrop) { - return make_shared(netStore); + return make_shared(netStore, rules); } else if (type == EntityType::Npc) { - return m_npcDatabase->netLoadNpc(netStore); + return m_npcDatabase->netLoadNpc(netStore, rules); } else if (type == EntityType::Stagehand) { - return make_shared(netStore); + return make_shared(netStore, rules); } else if (type == EntityType::Vehicle) { - return m_vehicleDatabase->netLoad(netStore); + return m_vehicleDatabase->netLoad(netStore, rules); } else { throw EntityFactoryException::format("Don't know how to create entity type '{}' from net store", EntityTypeNames.getRight(type)); } diff --git a/source/game/StarEntityFactory.hpp b/source/game/StarEntityFactory.hpp index 09d4e99..7d5c014 100644 --- a/source/game/StarEntityFactory.hpp +++ b/source/game/StarEntityFactory.hpp @@ -20,8 +20,8 @@ class EntityFactory { public: EntityFactory(); - ByteArray netStoreEntity(EntityPtr const& entity) const; - EntityPtr netLoadEntity(EntityType type, ByteArray const& netStore) const; + ByteArray netStoreEntity(EntityPtr const& entity, NetCompatibilityRules rules = {}) const; + EntityPtr netLoadEntity(EntityType type, ByteArray const& netStore, NetCompatibilityRules rules = {}) const; Json diskStoreEntity(EntityPtr const& entity) const; EntityPtr diskLoadEntity(EntityType type, Json const& diskStore) const; diff --git a/source/game/StarHumanoid.cpp b/source/game/StarHumanoid.cpp index 47368b1..d140881 100644 --- a/source/game/StarHumanoid.cpp +++ b/source/game/StarHumanoid.cpp @@ -243,6 +243,49 @@ EnumMap const Humanoid::StateNames{ }; Humanoid::Humanoid(Json const& config) { + loadConfig(config); + + m_twoHanded = false; + m_primaryHand.holdingItem = false; + m_altHand.holdingItem = false; + + m_movingBackwards = false; + m_altHand.angle = 0; + m_facingDirection = Direction::Left; + m_rotation = 0; + m_scale = Vec2F::filled(1.f); + m_drawVaporTrail = false; + m_state = State::Idle; + m_emoteState = HumanoidEmote::Idle; + m_dance = {}; + + m_primaryHand.angle = 0; + m_animationTimer = m_emoteAnimationTimer = m_danceTimer = 0.0f; +} + +Humanoid::Humanoid(HumanoidIdentity const& identity) + : Humanoid(Root::singleton().speciesDatabase()->species(identity.species)->humanoidConfig()) { + setIdentity(identity); +} + +void Humanoid::setIdentity(HumanoidIdentity const& identity) { + m_identity = identity; + m_headFrameset = getHeadFromIdentity(); + m_bodyFrameset = getBodyFromIdentity(); + m_emoteFrameset = getFacialEmotesFromIdentity(); + m_hairFrameset = getHairFromIdentity(); + m_facialHairFrameset = getFacialHairFromIdentity(); + m_facialMaskFrameset = getFacialMaskFromIdentity(); + m_backArmFrameset = getBackArmFromIdentity(); + m_frontArmFrameset = getFrontArmFromIdentity(); + m_vaporTrailFrameset = getVaporTrailFrameset(); +} + +HumanoidIdentity const& Humanoid::identity() const { + return m_identity; +} + +void Humanoid::loadConfig(Json const& config) { m_timing = HumanoidTiming(config.getObject("humanoidTiming")); m_globalOffset = jsonToVec2F(config.get("globalOffset")) / TilePixels; @@ -271,10 +314,13 @@ Humanoid::Humanoid(Json const& config) { m_armWalkSeq = jsonToIntList(config.get("armWalkSeq")); m_armRunSeq = jsonToIntList(config.get("armRunSeq")); + m_walkBob.clear(); for (auto const& v : config.get("walkBob").toArray()) m_walkBob.append(v.toDouble() / TilePixels); + m_runBob.clear(); for (auto const& v : config.get("runBob").toArray()) m_runBob.append(v.toDouble() / TilePixels); + m_swimBob.clear(); for (auto const& v : config.get("swimBob").toArray()) m_swimBob.append(v.toDouble() / TilePixels); @@ -290,46 +336,6 @@ Humanoid::Humanoid(Json const& config) { m_particleEmitters = config.get("particleEmitters"); m_defaultMovementParameters = config.get("movementParameters"); - - m_twoHanded = false; - m_primaryHand.holdingItem = false; - m_altHand.holdingItem = false; - - m_movingBackwards = false; - m_altHand.angle = 0; - m_facingDirection = Direction::Left; - m_rotation = 0; - m_scale = Vec2F::filled(1.f); - m_drawVaporTrail = false; - m_state = State::Idle; - m_emoteState = HumanoidEmote::Idle; - m_dance = {}; - m_emoteAnimationTimer = 0; - - m_primaryHand.angle = 0; - m_animationTimer = 0.0f; -} - -Humanoid::Humanoid(HumanoidIdentity const& identity) - : Humanoid(Root::singleton().speciesDatabase()->species(identity.species)->humanoidConfig()) { - setIdentity(identity); -} - -void Humanoid::setIdentity(HumanoidIdentity const& identity) { - m_identity = identity; - m_headFrameset = getHeadFromIdentity(); - m_bodyFrameset = getBodyFromIdentity(); - m_emoteFrameset = getFacialEmotesFromIdentity(); - m_hairFrameset = getHairFromIdentity(); - m_facialHairFrameset = getFacialHairFromIdentity(); - m_facialMaskFrameset = getFacialMaskFromIdentity(); - m_backArmFrameset = getBackArmFromIdentity(); - m_frontArmFrameset = getFrontArmFromIdentity(); - m_vaporTrailFrameset = getVaporTrailFrameset(); -} - -HumanoidIdentity const& Humanoid::identity() const { - return m_identity; } void Humanoid::setHeadArmorDirectives(Directives directives) { diff --git a/source/game/StarHumanoid.hpp b/source/game/StarHumanoid.hpp index 283f7e9..c83ddb5 100644 --- a/source/game/StarHumanoid.hpp +++ b/source/game/StarHumanoid.hpp @@ -125,6 +125,8 @@ public: void setIdentity(HumanoidIdentity const& identity); HumanoidIdentity const& identity() const; + void loadConfig(Json const& config); + // All of the image identifiers here are meant to be image *base* names, with // a collection of frames specific to each piece. If an image is set to // empty string, it is disabled. diff --git a/source/game/StarItemDrop.cpp b/source/game/StarItemDrop.cpp index bc3d15f..4d9dab1 100644 --- a/source/game/StarItemDrop.cpp +++ b/source/game/StarItemDrop.cpp @@ -92,9 +92,9 @@ ItemDrop::ItemDrop(Json const& diskStore) m_itemDescriptor.set(m_item->descriptor()); } -ItemDrop::ItemDrop(ByteArray store) - : ItemDrop() { +ItemDrop::ItemDrop(ByteArray store, NetCompatibilityRules rules) : ItemDrop() { DataStreamBuffer ds(std::move(store)); + ds.setStreamCompatibilityVersion(rules); Root::singleton().itemDatabase()->loadItem(ds.read(), m_item); ds.read(m_eternal); @@ -116,8 +116,9 @@ Json ItemDrop::diskStore() const { }; } -ByteArray ItemDrop::netStore() const { +ByteArray ItemDrop::netStore(NetCompatibilityRules rules) const { DataStreamBuffer ds; + ds.setStreamCompatibilityVersion(rules); ds.write(itemSafeDescriptor(m_item)); ds.write(m_eternal); @@ -146,12 +147,12 @@ String ItemDrop::description() const { return m_item->description(); } -pair ItemDrop::writeNetState(uint64_t fromVersion) { - return m_netGroup.writeNetState(fromVersion); +pair ItemDrop::writeNetState(uint64_t fromVersion, NetCompatibilityRules rules) { + return m_netGroup.writeNetState(fromVersion, rules); } -void ItemDrop::readNetState(ByteArray data, float interpolationTime) { - m_netGroup.readNetState(std::move(data), interpolationTime); +void ItemDrop::readNetState(ByteArray data, float interpolationTime, NetCompatibilityRules rules) { + m_netGroup.readNetState(data, interpolationTime, rules); } void ItemDrop::enableInterpolation(float extrapolationHint) { diff --git a/source/game/StarItemDrop.hpp b/source/game/StarItemDrop.hpp index 3d6e931..c551c01 100644 --- a/source/game/StarItemDrop.hpp +++ b/source/game/StarItemDrop.hpp @@ -27,10 +27,10 @@ public: ItemDrop(ItemPtr item); ItemDrop(Json const& diskStore); - ItemDrop(ByteArray netStore); + ItemDrop(ByteArray netStore, NetCompatibilityRules rules = {}); Json diskStore() const; - ByteArray netStore() const; + ByteArray netStore(NetCompatibilityRules rules = {}) const; EntityType entityType() const override; @@ -39,8 +39,8 @@ public: String description() const override; - pair writeNetState(uint64_t fromVersion = 0) override; - void readNetState(ByteArray data, float interpolationTime = 0.0f) override; + pair writeNetState(uint64_t fromVersion = 0, NetCompatibilityRules rules = {}) override; + void readNetState(ByteArray data, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; void enableInterpolation(float extrapolationHint = 0.0f) override; void disableInterpolation() override; diff --git a/source/game/StarMonster.cpp b/source/game/StarMonster.cpp index 05eaeb3..d9ce986 100644 --- a/source/game/StarMonster.cpp +++ b/source/game/StarMonster.cpp @@ -110,8 +110,8 @@ Json Monster::diskStore() const { }; } -ByteArray Monster::netStore() { - return Root::singleton().monsterDatabase()->writeMonsterVariant(m_monsterVariant); +ByteArray Monster::netStore(NetCompatibilityRules rules) { + return Root::singleton().monsterDatabase()->writeMonsterVariant(m_monsterVariant, rules); } EntityType Monster::entityType() const { @@ -210,12 +210,12 @@ Vec2F Monster::velocity() const { return m_movementController->velocity(); } -pair Monster::writeNetState(uint64_t fromVersion) { - return m_netGroup.writeNetState(fromVersion); +pair Monster::writeNetState(uint64_t fromVersion, NetCompatibilityRules rules) { + return m_netGroup.writeNetState(fromVersion, rules); } -void Monster::readNetState(ByteArray data, float interpolationTime) { - m_netGroup.readNetState(std::move(data), interpolationTime); +void Monster::readNetState(ByteArray data, float interpolationTime, NetCompatibilityRules rules) { + m_netGroup.readNetState(data, interpolationTime, rules); } void Monster::enableInterpolation(float extrapolationHint) { diff --git a/source/game/StarMonster.hpp b/source/game/StarMonster.hpp index d6cae3e..5c964e3 100644 --- a/source/game/StarMonster.hpp +++ b/source/game/StarMonster.hpp @@ -42,7 +42,7 @@ public: Monster(Json const& diskStore); Json diskStore() const; - ByteArray netStore(); + ByteArray netStore(NetCompatibilityRules rules = {}); EntityType entityType() const override; ClientEntityMode clientEntityMode() const override; @@ -60,8 +60,8 @@ public: RectF collisionArea() const override; - pair writeNetState(uint64_t fromVersion = 0) override; - void readNetState(ByteArray data, float interpolationTime = 0.0f) override; + pair writeNetState(uint64_t fromVersion = 0, NetCompatibilityRules rules = {}) override; + void readNetState(ByteArray data, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; void enableInterpolation(float extrapolationHint) override; void disableInterpolation() override; diff --git a/source/game/StarMonsterDatabase.cpp b/source/game/StarMonsterDatabase.cpp index 963cf87..2b86d44 100644 --- a/source/game/StarMonsterDatabase.cpp +++ b/source/game/StarMonsterDatabase.cpp @@ -170,8 +170,9 @@ MonsterVariant MonsterDatabase::monsterVariant(String const& typeName, uint64_t }); } -ByteArray MonsterDatabase::writeMonsterVariant(MonsterVariant const& variant) const { +ByteArray MonsterDatabase::writeMonsterVariant(MonsterVariant const& variant, NetCompatibilityRules rules) const { DataStreamBuffer ds; + ds.setStreamCompatibilityVersion(rules); ds.write(variant.type); ds.write(variant.seed); @@ -180,8 +181,9 @@ ByteArray MonsterDatabase::writeMonsterVariant(MonsterVariant const& variant) co return ds.data(); } -MonsterVariant MonsterDatabase::readMonsterVariant(ByteArray const& data) const { +MonsterVariant MonsterDatabase::readMonsterVariant(ByteArray const& data, NetCompatibilityRules rules) const { DataStreamBuffer ds(data); + ds.setStreamCompatibilityVersion(rules); String type = ds.read(); uint64_t seed = ds.read(); @@ -216,8 +218,8 @@ MonsterPtr MonsterDatabase::diskLoadMonster(Json const& diskStore) const { return make_shared(diskStore); } -MonsterPtr MonsterDatabase::netLoadMonster(ByteArray const& netStore) const { - return make_shared(readMonsterVariant(netStore)); +MonsterPtr MonsterDatabase::netLoadMonster(ByteArray const& netStore, NetCompatibilityRules rules) const { + return make_shared(readMonsterVariant(netStore, rules)); } List MonsterDatabase::monsterPortrait(MonsterVariant const& variant) const { diff --git a/source/game/StarMonsterDatabase.hpp b/source/game/StarMonsterDatabase.hpp index 9147542..0220267 100644 --- a/source/game/StarMonsterDatabase.hpp +++ b/source/game/StarMonsterDatabase.hpp @@ -96,8 +96,8 @@ public: MonsterVariant randomMonster(String const& typeName, Json const& uniqueParameters = JsonObject()) const; MonsterVariant monsterVariant(String const& typeName, uint64_t seed, Json const& uniqueParameters = JsonObject()) const; - ByteArray writeMonsterVariant(MonsterVariant const& variant) const; - MonsterVariant readMonsterVariant(ByteArray const& data) const; + ByteArray writeMonsterVariant(MonsterVariant const& variant, NetCompatibilityRules rules = {}) const; + MonsterVariant readMonsterVariant(ByteArray const& data, NetCompatibilityRules rules = {}) const; Json writeMonsterVariantToJson(MonsterVariant const& mVar) const; MonsterVariant readMonsterVariantFromJson(Json const& variant) const; @@ -106,7 +106,7 @@ public: // whatever world they're spawned in. MonsterPtr createMonster(MonsterVariant monsterVariant, Maybe level = {}, Json uniqueParameters = {}) const; MonsterPtr diskLoadMonster(Json const& diskStore) const; - MonsterPtr netLoadMonster(ByteArray const& netStore) const; + MonsterPtr netLoadMonster(ByteArray const& netStore, NetCompatibilityRules rules = {}) const; List monsterPortrait(MonsterVariant const& variant) const; diff --git a/source/game/StarNetPackets.cpp b/source/game/StarNetPackets.cpp index b8605ed..dd80d76 100644 --- a/source/game/StarNetPackets.cpp +++ b/source/game/StarNetPackets.cpp @@ -5,6 +5,7 @@ namespace Star { VersionNumber const StarProtocolVersion = 747; +VersionNumber const OpenProtocolVersion = 1; EnumMap const PacketTypeNames{ {PacketType::ProtocolRequest, "ProtocolRequest"}, diff --git a/source/game/StarNetPackets.hpp b/source/game/StarNetPackets.hpp index 6181b30..e68a045 100644 --- a/source/game/StarNetPackets.hpp +++ b/source/game/StarNetPackets.hpp @@ -14,6 +14,7 @@ #include "StarWiring.hpp" #include "StarClientContext.hpp" #include "StarSystemWorld.hpp" +#include "StarNetCompatibility.hpp" namespace Star { @@ -22,6 +23,7 @@ STAR_STRUCT(Packet); STAR_EXCEPTION(StarPacketException, IOException); extern VersionNumber const StarProtocolVersion; +extern VersionNumber const OpenProtocolVersion; // Packet types sent between the client and server over a NetSocket. Does not // correspond to actual packets, simply logical portions of NetSocket data. diff --git a/source/game/StarNpc.cpp b/source/game/StarNpc.cpp index c68fd08..388f6e5 100644 --- a/source/game/StarNpc.cpp +++ b/source/game/StarNpc.cpp @@ -152,8 +152,8 @@ Json Npc::diskStore() const { }; } -ByteArray Npc::netStore() { - return Root::singleton().npcDatabase()->writeNpcVariant(m_npcVariant); +ByteArray Npc::netStore(NetCompatibilityRules rules) { + return Root::singleton().npcDatabase()->writeNpcVariant(m_npcVariant, rules); } EntityType Npc::entityType() const { @@ -252,7 +252,7 @@ RectF Npc::collisionArea() const { return m_movementController->collisionPoly().boundBox(); } -pair Npc::writeNetState(uint64_t fromVersion) { +pair Npc::writeNetState(uint64_t fromVersion, NetCompatibilityRules rules) { // client-side npcs error nearby vanilla NPC scripts because callScriptedEntity // for now, scrungle the collision poly to avoid their queries. hacky :( if (m_npcVariant.overrides && m_npcVariant.overrides.getBool("overrideNetPoly", false)) { @@ -260,18 +260,18 @@ pair Npc::writeNetState(uint64_t fromVersion) { if (*mode == EntityMode::Master && connectionForEntity(entityId()) != ServerConnectionId) { PolyF poly = m_movementController->collisionPoly(); m_movementController->setCollisionPoly({ { 0.0f, -3.402823466e+38F }}); - auto result = m_netGroup.writeNetState(fromVersion); + auto result = m_netGroup.writeNetState(fromVersion, rules); m_movementController->setCollisionPoly(poly); return result; } } } - return m_netGroup.writeNetState(fromVersion); + return m_netGroup.writeNetState(fromVersion, rules); } -void Npc::readNetState(ByteArray data, float interpolationTime) { - m_netGroup.readNetState(std::move(data), interpolationTime); +void Npc::readNetState(ByteArray data, float interpolationTime, NetCompatibilityRules rules) { + m_netGroup.readNetState(data, interpolationTime, rules); } String Npc::description() const { diff --git a/source/game/StarNpc.hpp b/source/game/StarNpc.hpp index ab8bc0f..0b22702 100644 --- a/source/game/StarNpc.hpp +++ b/source/game/StarNpc.hpp @@ -42,11 +42,12 @@ class Npc public virtual PhysicsEntity, public virtual EmoteEntity { public: + Npc(ByteArray const& netStore, NetCompatibilityRules rules = {}); Npc(NpcVariant const& npcVariant); Npc(NpcVariant const& npcVariant, Json const& initialState); Json diskStore() const; - ByteArray netStore(); + ByteArray netStore(NetCompatibilityRules rules = {}); EntityType entityType() const override; ClientEntityMode clientEntityMode() const override; @@ -66,8 +67,8 @@ public: RectF collisionArea() const override; - pair writeNetState(uint64_t fromVersion = 0) override; - void readNetState(ByteArray data, float interpolationTime = 0.0f) override; + pair writeNetState(uint64_t fromVersion = 0, NetCompatibilityRules rules = {}) override; + void readNetState(ByteArray data, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; void enableInterpolation(float extrapolationHint = 0.0f) override; void disableInterpolation() override; diff --git a/source/game/StarNpcDatabase.cpp b/source/game/StarNpcDatabase.cpp index bd70df5..392b29d 100644 --- a/source/game/StarNpcDatabase.cpp +++ b/source/game/StarNpcDatabase.cpp @@ -157,8 +157,9 @@ NpcVariant NpcDatabase::generateNpcVariant( return variant; } -ByteArray NpcDatabase::writeNpcVariant(NpcVariant const& variant) const { +ByteArray NpcDatabase::writeNpcVariant(NpcVariant const& variant, NetCompatibilityRules rules) const { DataStreamBuffer ds; + ds.setStreamCompatibilityVersion(rules); ds.write(variant.species); ds.write(variant.typeName); @@ -179,8 +180,9 @@ ByteArray NpcDatabase::writeNpcVariant(NpcVariant const& variant) const { return ds.data(); } -NpcVariant NpcDatabase::readNpcVariant(ByteArray const& data) const { +NpcVariant NpcDatabase::readNpcVariant(ByteArray const& data, NetCompatibilityRules rules) const { DataStreamBuffer ds(data); + ds.setStreamCompatibilityVersion(rules); NpcVariant variant; @@ -325,8 +327,8 @@ NpcPtr NpcDatabase::diskLoadNpc(Json const& diskStore) const { return make_shared(npcVariant, diskStore); } -NpcPtr NpcDatabase::netLoadNpc(ByteArray const& netStore) const { - return make_shared(readNpcVariant(netStore)); +NpcPtr NpcDatabase::netLoadNpc(ByteArray const& netStore, NetCompatibilityRules rules) const { + return make_shared(readNpcVariant(netStore, rules)); } List NpcDatabase::npcPortrait(NpcVariant const& npcVariant, PortraitMode mode) const { diff --git a/source/game/StarNpcDatabase.hpp b/source/game/StarNpcDatabase.hpp index 01dec97..a97d0f5 100644 --- a/source/game/StarNpcDatabase.hpp +++ b/source/game/StarNpcDatabase.hpp @@ -58,15 +58,15 @@ public: NpcVariant generateNpcVariant(String const& species, String const& typeName, float level) const; NpcVariant generateNpcVariant(String const& species, String const& typeName, float level, uint64_t seed, Json const& overrides) const; - ByteArray writeNpcVariant(NpcVariant const& variant) const; - NpcVariant readNpcVariant(ByteArray const& data) const; + ByteArray writeNpcVariant(NpcVariant const& variant, NetCompatibilityRules rules = {}) const; + NpcVariant readNpcVariant(ByteArray const& data, NetCompatibilityRules rules = {}) const; Json writeNpcVariantToJson(NpcVariant const& variant) const; NpcVariant readNpcVariantFromJson(Json const& data) const; NpcPtr createNpc(NpcVariant const& npcVariant) const; - NpcPtr diskLoadNpc(Json const& diskStoree) const; - NpcPtr netLoadNpc(ByteArray const& netStore) const; + NpcPtr diskLoadNpc(Json const& diskStore) const; + NpcPtr netLoadNpc(ByteArray const& netStore, NetCompatibilityRules rules = {}) const; List npcPortrait(NpcVariant const& npcVariant, PortraitMode mode) const; diff --git a/source/game/StarObject.cpp b/source/game/StarObject.cpp index ece0b20..66f7917 100644 --- a/source/game/StarObject.cpp +++ b/source/game/StarObject.cpp @@ -118,8 +118,9 @@ Json Object::diskStore() const { return writeStoredData().setAll({{"name", m_config->name}, {"parameters", m_parameters.baseMap()}}); } -ByteArray Object::netStore() { +ByteArray Object::netStore(NetCompatibilityRules rules) { DataStreamBuffer ds; + ds.setStreamCompatibilityVersion(rules); ds.write(m_config->name); ds.write(m_parameters.baseMap()); return ds.takeData(); @@ -297,13 +298,12 @@ RectF Object::metaBoundBox() const { } } -pair Object::writeNetState(uint64_t fromVersion) { - DataStreamBuffer ds; - return m_netGroup.writeNetState(fromVersion); +pair Object::writeNetState(uint64_t fromVersion, NetCompatibilityRules rules) { + return m_netGroup.writeNetState(fromVersion, rules); } -void Object::readNetState(ByteArray delta, float interpolationTime) { - m_netGroup.readNetState(std::move(delta), interpolationTime); +void Object::readNetState(ByteArray data, float interpolationTime, NetCompatibilityRules rules) { + m_netGroup.readNetState(data, interpolationTime, rules); } Vec2I Object::tilePosition() const { diff --git a/source/game/StarObject.hpp b/source/game/StarObject.hpp index a797842..e768ca8 100644 --- a/source/game/StarObject.hpp +++ b/source/game/StarObject.hpp @@ -37,7 +37,7 @@ public: Object(ObjectConfigConstPtr config, Json const& parameters = JsonObject()); Json diskStore() const; - ByteArray netStore(); + ByteArray netStore(NetCompatibilityRules rules = {}); virtual EntityType entityType() const override; virtual ClientEntityMode clientEntityMode() const override; @@ -48,8 +48,8 @@ public: virtual Vec2F position() const override; virtual RectF metaBoundBox() const override; - virtual pair writeNetState(uint64_t fromVersion = 0) override; - virtual void readNetState(ByteArray data, float interpolationTime = 0.0f) override; + virtual pair writeNetState(uint64_t fromVersion = 0, NetCompatibilityRules rules = {}) override; + virtual void readNetState(ByteArray data, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; virtual String description() const override; diff --git a/source/game/StarObjectDatabase.cpp b/source/game/StarObjectDatabase.cpp index 8ed56e4..71eb166 100644 --- a/source/game/StarObjectDatabase.cpp +++ b/source/game/StarObjectDatabase.cpp @@ -380,8 +380,9 @@ ObjectPtr ObjectDatabase::diskLoadObject(Json const& diskStore) const { return object; } -ObjectPtr ObjectDatabase::netLoadObject(ByteArray const& netStore) const { +ObjectPtr ObjectDatabase::netLoadObject(ByteArray const& netStore, NetCompatibilityRules rules) const { DataStreamBuffer ds(netStore); + ds.setStreamCompatibilityVersion(rules); String name = ds.read(); Json parameters = ds.read(); return createObject(name, parameters); diff --git a/source/game/StarObjectDatabase.hpp b/source/game/StarObjectDatabase.hpp index ca44c2e..b431445 100644 --- a/source/game/StarObjectDatabase.hpp +++ b/source/game/StarObjectDatabase.hpp @@ -198,7 +198,7 @@ public: ObjectPtr createObject(String const& objectName, Json const& objectParameters = JsonObject()) const; ObjectPtr diskLoadObject(Json const& diskStore) const; - ObjectPtr netLoadObject(ByteArray const& netStore) const; + ObjectPtr netLoadObject(ByteArray const& netStore, NetCompatibilityRules rules = {}) const; bool canPlaceObject(World const* world, Vec2I const& position, String const& objectName) const; // If the object is placeable in the given position, creates the given object diff --git a/source/game/StarPlant.cpp b/source/game/StarPlant.cpp index 7b4e426..32e1575 100644 --- a/source/game/StarPlant.cpp +++ b/source/game/StarPlant.cpp @@ -411,8 +411,9 @@ Json Plant::diskStore() const { }; } -ByteArray Plant::netStore() const { +ByteArray Plant::netStore(NetCompatibilityRules rules) const { DataStreamBuffer ds; + ds.setStreamCompatibilityVersion(rules); ds.viwrite(m_tilePosition[0]); ds.viwrite(m_tilePosition[1]); ds.write(m_ceiling); @@ -423,7 +424,7 @@ ByteArray Plant::netStore() const { ds.write(m_ephemeral); ds.write(m_tileDamageParameters); ds.write(m_fallsWhenDead); - m_tileDamageStatus.netStore(ds); + m_tileDamageStatus.netStore(ds, rules); ds.write(writePieces()); return ds.takeData(); @@ -534,7 +535,7 @@ Plant::Plant(Json const& diskStore) : Plant() { setupNetStates(); } -Plant::Plant(ByteArray const& netStore) : Plant() { +Plant::Plant(ByteArray const& netStore, NetCompatibilityRules rules) : Plant() { m_broken = false; m_tilePosition = Vec2I(); m_ceiling = false; @@ -545,6 +546,7 @@ Plant::Plant(ByteArray const& netStore) : Plant() { m_piecesUpdated = true; DataStreamBuffer ds(netStore); + ds.setStreamCompatibilityVersion(rules); ds.viread(m_tilePosition[0]); ds.viread(m_tilePosition[1]); ds.read(m_ceiling); @@ -555,7 +557,7 @@ Plant::Plant(ByteArray const& netStore) : Plant() { ds.read(m_ephemeral); ds.read(m_tileDamageParameters); ds.read(m_fallsWhenDead); - m_tileDamageStatus.netLoad(ds); + m_tileDamageStatus.netLoad(ds, rules); readPieces(ds.read()); setupNetStates(); @@ -586,12 +588,12 @@ void Plant::init(World* world, EntityId entityId, EntityMode mode) { m_tilePosition = world->geometry().xwrap(m_tilePosition); } -pair Plant::writeNetState(uint64_t fromVersion) { - return m_netGroup.writeNetState(fromVersion); +pair Plant::writeNetState(uint64_t fromVersion, NetCompatibilityRules rules) { + return m_netGroup.writeNetState(fromVersion, rules); } -void Plant::readNetState(ByteArray data, float interpolationTime) { - m_netGroup.readNetState(std::move(data), interpolationTime); +void Plant::readNetState(ByteArray data, float interpolationTime, NetCompatibilityRules rules) { + m_netGroup.readNetState(data, interpolationTime, rules); } void Plant::enableInterpolation(float extrapolationHint) { diff --git a/source/game/StarPlant.hpp b/source/game/StarPlant.hpp index 53aed5f..ddb9501 100644 --- a/source/game/StarPlant.hpp +++ b/source/game/StarPlant.hpp @@ -57,10 +57,10 @@ public: Plant(GrassVariant const& config, uint64_t seed); Plant(BushVariant const& config, uint64_t seed); Plant(Json const& diskStore); - Plant(ByteArray const& netStore); + Plant(ByteArray const& netStore, NetCompatibilityRules rules = {}); Json diskStore() const; - ByteArray netStore() const; + ByteArray netStore(NetCompatibilityRules rules = {}) const; EntityType entityType() const override; @@ -68,8 +68,8 @@ public: virtual String description() const override; - pair writeNetState(uint64_t fromVersion = 0) override; - void readNetState(ByteArray data, float interpolationTime = 0.0f) override; + pair writeNetState(uint64_t fromVersion = 0, NetCompatibilityRules rules = {}) override; + void readNetState(ByteArray data, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; void enableInterpolation(float extrapolationHint) override; void disableInterpolation() override; diff --git a/source/game/StarPlantDrop.cpp b/source/game/StarPlantDrop.cpp index ccb57d8..b41705d 100644 --- a/source/game/StarPlantDrop.cpp +++ b/source/game/StarPlantDrop.cpp @@ -86,11 +86,12 @@ PlantDrop::PlantDrop(List pieces, Vec2F const& position, Vec2 m_collisionRect = fullBounds; } -PlantDrop::PlantDrop(ByteArray const& netStore) { +PlantDrop::PlantDrop(ByteArray const& netStore, NetCompatibilityRules rules) { m_netGroup.addNetElement(&m_movementController); m_netGroup.addNetElement(&m_spawnedDrops); DataStreamBuffer ds(netStore); + ds.setStreamCompatibilityVersion(rules); ds >> m_time; ds >> m_master; ds >> m_description; @@ -113,7 +114,7 @@ PlantDrop::PlantDrop(ByteArray const& netStore) { m_spawnedDropEffects = true; } -ByteArray PlantDrop::netStore() { +ByteArray PlantDrop::netStore(NetCompatibilityRules rules) { DataStreamBuffer ds; ds << m_time; ds << m_master; @@ -358,12 +359,12 @@ void PlantDrop::render(RenderCallback* renderCallback) { } } -pair PlantDrop::writeNetState(uint64_t fromVersion) { - return m_netGroup.writeNetState(fromVersion); +pair PlantDrop::writeNetState(uint64_t fromVersion, NetCompatibilityRules rules) { + return m_netGroup.writeNetState(fromVersion, rules); } -void PlantDrop::readNetState(ByteArray data, float interpolationTime) { - m_netGroup.readNetState(std::move(data), interpolationTime); +void PlantDrop::readNetState(ByteArray data, float interpolationTime, NetCompatibilityRules rules) { + m_netGroup.readNetState(data, interpolationTime, rules); } void PlantDrop::enableInterpolation(float extrapolationHint) { diff --git a/source/game/StarPlantDrop.hpp b/source/game/StarPlantDrop.hpp index 1b630f4..7528e5d 100644 --- a/source/game/StarPlantDrop.hpp +++ b/source/game/StarPlantDrop.hpp @@ -15,9 +15,9 @@ public: PlantDrop(List pieces, Vec2F const& position, Vec2F const& strikeVector, String const& description, bool upsideDown, Json stemConfig, Json foliageConfig, Json saplingConfig, bool master, float random); - PlantDrop(ByteArray const& netStore); + PlantDrop(ByteArray const& netStore, NetCompatibilityRules rules = {}); - ByteArray netStore(); + ByteArray netStore(NetCompatibilityRules rules = {}); EntityType entityType() const override; @@ -26,8 +26,8 @@ public: String description() const override; - pair writeNetState(uint64_t fromVersion = 0) override; - void readNetState(ByteArray data, float interpolationTime = 0.0f) override; + pair writeNetState(uint64_t fromVersion = 0, NetCompatibilityRules rules = {}) override; + void readNetState(ByteArray data, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; void enableInterpolation(float extrapolationHint = 0.0f) override; void disableInterpolation() override; diff --git a/source/game/StarPlayer.cpp b/source/game/StarPlayer.cpp index 9c9c482..8ee6d7a 100644 --- a/source/game/StarPlayer.cpp +++ b/source/game/StarPlayer.cpp @@ -187,8 +187,9 @@ Player::Player(PlayerConfigPtr config, Uuid uuid) { m_netGroup.setNeedsStoreCallback(bind(&Player::setNetStates, this)); } -Player::Player(PlayerConfigPtr config, ByteArray const& netStore) : Player(config) { +Player::Player(PlayerConfigPtr config, ByteArray const& netStore, NetCompatibilityRules rules) : Player(config) { DataStreamBuffer ds(netStore); + ds.setStreamCompatibilityVersion(rules); setUniqueId(ds.read()); @@ -1618,12 +1619,12 @@ Direction Player::facingDirection() const { return m_movementController->facingDirection(); } -pair Player::writeNetState(uint64_t fromVersion) { - return m_netGroup.writeNetState(fromVersion); +pair Player::writeNetState(uint64_t fromVersion, NetCompatibilityRules rules) { + return m_netGroup.writeNetState(fromVersion, rules); } -void Player::readNetState(ByteArray data, float interpolationTime) { - m_netGroup.readNetState(std::move(data), interpolationTime); +void Player::readNetState(ByteArray data, float interpolationTime, NetCompatibilityRules rules) { + m_netGroup.readNetState(data, interpolationTime, rules); } void Player::enableInterpolation(float) { @@ -2319,8 +2320,9 @@ Json Player::diskStore() { }; } -ByteArray Player::netStore() { +ByteArray Player::netStore(NetCompatibilityRules rules) { DataStreamBuffer ds; + ds.setStreamCompatibilityVersion(rules); ds.write(*uniqueId()); ds.write(m_description); diff --git a/source/game/StarPlayer.hpp b/source/game/StarPlayer.hpp index 871ca47..f6e32e0 100644 --- a/source/game/StarPlayer.hpp +++ b/source/game/StarPlayer.hpp @@ -76,7 +76,7 @@ public: static EnumMap const StateNames; Player(PlayerConfigPtr config, Uuid uuid = Uuid()); - Player(PlayerConfigPtr config, ByteArray const& netStore); + Player(PlayerConfigPtr config, ByteArray const& netStore, NetCompatibilityRules rules = {}); Player(PlayerConfigPtr config, Json const& diskStore); void diskLoad(Json const& diskStore); @@ -92,7 +92,7 @@ public: QuestManagerPtr questManager() const; Json diskStore(); - ByteArray netStore(); + ByteArray netStore(NetCompatibilityRules rules = {}); EntityType entityType() const override; ClientEntityMode clientEntityMode() const override; @@ -118,8 +118,8 @@ public: // relative to current position RectF collisionArea() const override; - pair writeNetState(uint64_t fromStep = 0) override; - void readNetState(ByteArray data, float interpolationStep = 0.0f) override; + pair writeNetState(uint64_t fromVersion = 0, NetCompatibilityRules rules = {}) override; + void readNetState(ByteArray data, float interpolationStep = 0.0f, NetCompatibilityRules rules = {}) override; void enableInterpolation(float extrapolationHint = 0.0f) override; void disableInterpolation() override; diff --git a/source/game/StarPlayerFactory.cpp b/source/game/StarPlayerFactory.cpp index f3dbf29..43854b6 100644 --- a/source/game/StarPlayerFactory.cpp +++ b/source/game/StarPlayerFactory.cpp @@ -60,8 +60,8 @@ PlayerPtr PlayerFactory::diskLoadPlayer(Json const& diskStore) const { return make_shared(m_config, diskStore); } -PlayerPtr PlayerFactory::netLoadPlayer(ByteArray const& netStore) const { - return make_shared(m_config, netStore); +PlayerPtr PlayerFactory::netLoadPlayer(ByteArray const& netStore, NetCompatibilityRules rules) const { + return make_shared(m_config, netStore, rules); } } diff --git a/source/game/StarPlayerFactory.hpp b/source/game/StarPlayerFactory.hpp index a366221..6712b81 100644 --- a/source/game/StarPlayerFactory.hpp +++ b/source/game/StarPlayerFactory.hpp @@ -60,7 +60,7 @@ public: PlayerPtr create() const; PlayerPtr diskLoadPlayer(Json const& diskStore) const; - PlayerPtr netLoadPlayer(ByteArray const& netStore) const; + PlayerPtr netLoadPlayer(ByteArray const& netStore, NetCompatibilityRules rules = {}) const; private: PlayerConfigPtr m_config; diff --git a/source/game/StarProjectile.cpp b/source/game/StarProjectile.cpp index 1503f4c..47cb973 100644 --- a/source/game/StarProjectile.cpp +++ b/source/game/StarProjectile.cpp @@ -27,7 +27,7 @@ Projectile::Projectile(ProjectileConfigPtr const& config, Json const& parameters setup(); } -Projectile::Projectile(ProjectileConfigPtr const& config, DataStreamBuffer& data) { +Projectile::Projectile(ProjectileConfigPtr const& config, DataStreamBuffer& data, NetCompatibilityRules rules) { m_config = config; data.read(m_parameters); setup(); @@ -41,8 +41,9 @@ Projectile::Projectile(ProjectileConfigPtr const& config, DataStreamBuffer& data setTeam(data.read()); } -ByteArray Projectile::netStore() const { +ByteArray Projectile::netStore(NetCompatibilityRules rules) const { DataStreamBuffer ds; + ds.setStreamCompatibilityVersion(rules); ds.write(m_config->typeName); ds.write(m_parameters); @@ -141,12 +142,12 @@ Vec2F Projectile::velocity() const { return m_movementController->velocity(); } -pair Projectile::writeNetState(uint64_t fromVersion) { - return m_netGroup.writeNetState(fromVersion); +pair Projectile::writeNetState(uint64_t fromVersion, NetCompatibilityRules rules) { + return m_netGroup.writeNetState(fromVersion, rules); } -void Projectile::readNetState(ByteArray data, float interpolationTime) { - m_netGroup.readNetState(std::move(data), interpolationTime); +void Projectile::readNetState(ByteArray data, float interpolationTime, NetCompatibilityRules rules) { + m_netGroup.readNetState(data, interpolationTime, rules); } void Projectile::enableInterpolation(float extrapolationHint) { diff --git a/source/game/StarProjectile.hpp b/source/game/StarProjectile.hpp index 2aec4b4..fdafdbd 100644 --- a/source/game/StarProjectile.hpp +++ b/source/game/StarProjectile.hpp @@ -22,9 +22,9 @@ STAR_CLASS(Projectile); class Projectile : public virtual Entity, public virtual ScriptedEntity, public virtual PhysicsEntity, public virtual StatusEffectEntity { public: Projectile(ProjectileConfigPtr const& config, Json const& parameters); - Projectile(ProjectileConfigPtr const& config, DataStreamBuffer& netState); + Projectile(ProjectileConfigPtr const& config, DataStreamBuffer& netState, NetCompatibilityRules rules = {}); - ByteArray netStore() const; + ByteArray netStore(NetCompatibilityRules rules = {}) const; EntityType entityType() const override; @@ -43,8 +43,8 @@ public: ClientEntityMode clientEntityMode() const override; bool masterOnly() const override; - pair writeNetState(uint64_t fromVersion = 0) override; - void readNetState(ByteArray data, float interpolationTime = 0.0f) override; + pair writeNetState(uint64_t fromVersion = 0, NetCompatibilityRules rules = {}) override; + void readNetState(ByteArray data, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; void enableInterpolation(float extrapolationHint = 0.0f) override; void disableInterpolation() override; diff --git a/source/game/StarProjectileDatabase.cpp b/source/game/StarProjectileDatabase.cpp index c2a0c26..bb7fbc7 100644 --- a/source/game/StarProjectileDatabase.cpp +++ b/source/game/StarProjectileDatabase.cpp @@ -58,10 +58,11 @@ float ProjectileDatabase::gravityMultiplier(String const& type) const { return config->movementSettings.getFloat("gravityMultiplier", 1); } -ProjectilePtr ProjectileDatabase::netLoadProjectile(ByteArray const& netStore) const { +ProjectilePtr ProjectileDatabase::netLoadProjectile(ByteArray const& netStore, NetCompatibilityRules rules) const { DataStreamBuffer ds(netStore); + ds.setStreamCompatibilityVersion(rules); String typeName = ds.read(); - return make_shared(m_configs.get(typeName), ds); + return make_shared(m_configs.get(typeName), ds, rules); } ProjectileConfigPtr ProjectileDatabase::readConfig(String const& path) { diff --git a/source/game/StarProjectileDatabase.hpp b/source/game/StarProjectileDatabase.hpp index d3cdd3d..dbd7299 100644 --- a/source/game/StarProjectileDatabase.hpp +++ b/source/game/StarProjectileDatabase.hpp @@ -111,7 +111,7 @@ public: float gravityMultiplier(String const& type) const; ProjectilePtr createProjectile(String const& type, Json const& parameters = JsonObject()) const; - ProjectilePtr netLoadProjectile(ByteArray const& netStore) const; + ProjectilePtr netLoadProjectile(ByteArray const& netStore, NetCompatibilityRules rules = {}) const; private: ProjectileConfigPtr readConfig(String const& path); diff --git a/source/game/StarServerClientContext.cpp b/source/game/StarServerClientContext.cpp index 838dae0..fcbffbd 100644 --- a/source/game/StarServerClientContext.cpp +++ b/source/game/StarServerClientContext.cpp @@ -10,10 +10,11 @@ namespace Star { -ServerClientContext::ServerClientContext(ConnectionId clientId, Maybe remoteAddress, Uuid playerUuid, +ServerClientContext::ServerClientContext(ConnectionId clientId, Maybe remoteAddress, NetCompatibilityRules netRules, Uuid playerUuid, String playerName, String playerSpecies, bool canBecomeAdmin, WorldChunks initialShipChunks) : m_clientId(clientId), m_remoteAddress(remoteAddress), + m_netRules(netRules), m_playerUuid(playerUuid), m_playerName(playerName), m_playerSpecies(playerSpecies), @@ -88,6 +89,10 @@ bool ServerClientContext::canBecomeAdmin() const { return m_canBecomeAdmin; } +NetCompatibilityRules ServerClientContext::netRules() const { + return m_netRules; +} + String ServerClientContext::descriptiveName() const { RecursiveMutexLocker locker(m_mutex); String hostName = m_remoteAddress ? toString(*m_remoteAddress) : "local"; @@ -184,7 +189,7 @@ ByteArray ServerClientContext::writeUpdate() { shipChunksUpdate = DataStreamBuffer::serialize(take(m_shipChunksUpdate)); ByteArray netGroupUpdate; - tie(netGroupUpdate, m_netVersion) = m_netGroup.writeNetState(m_netVersion); + tie(netGroupUpdate, m_netVersion) = m_netGroup.writeNetState(m_netVersion, m_netRules); if (rpcUpdate.empty() && shipChunksUpdate.empty() && netGroupUpdate.empty()) return {}; diff --git a/source/game/StarServerClientContext.hpp b/source/game/StarServerClientContext.hpp index 9dbab43..7c54765 100644 --- a/source/game/StarServerClientContext.hpp +++ b/source/game/StarServerClientContext.hpp @@ -19,7 +19,7 @@ STAR_CLASS(ServerClientContext); class ServerClientContext { public: - ServerClientContext(ConnectionId clientId, Maybe remoteAddress, Uuid playerUuid, + ServerClientContext(ConnectionId clientId, Maybe remoteAddress, NetCompatibilityRules netRules, Uuid playerUuid, String playerName, String playerSpecies, bool canBecomeAdmin, WorldChunks initialShipChunks); ConnectionId clientId() const; @@ -28,6 +28,7 @@ public: String const& playerName() const; String const& playerSpecies() const; bool canBecomeAdmin() const; + NetCompatibilityRules netRules() const; String descriptiveName() const; // Register additional rpc methods from other server side services. @@ -87,6 +88,7 @@ public: private: ConnectionId const m_clientId; Maybe const m_remoteAddress; + NetCompatibilityRules m_netRules; Uuid const m_playerUuid; String const m_playerName; String const m_playerSpecies; diff --git a/source/game/StarSky.cpp b/source/game/StarSky.cpp index d9ac03a..51e5b73 100644 --- a/source/game/StarSky.cpp +++ b/source/game/StarSky.cpp @@ -66,12 +66,12 @@ void Sky::jumpTo(SkyParameters skyParameters) { m_skyParametersUpdated = true; } -pair Sky::writeUpdate(uint64_t fromVersion) { - return m_netGroup.writeNetState(fromVersion); +pair Sky::writeUpdate(uint64_t fromVersion, NetCompatibilityRules rules) { + return m_netGroup.writeNetState(fromVersion, rules); } -void Sky::readUpdate(ByteArray data) { - m_netGroup.readNetState(std::move(data)); +void Sky::readUpdate(ByteArray data, NetCompatibilityRules rules) { + m_netGroup.readNetState(std::move(data), 0.0f, rules); } void Sky::stateUpdate() { diff --git a/source/game/StarSky.hpp b/source/game/StarSky.hpp index 4f6ec0c..6065a9d 100644 --- a/source/game/StarSky.hpp +++ b/source/game/StarSky.hpp @@ -30,8 +30,8 @@ public: void jumpTo(SkyParameters SkyParameters); - pair writeUpdate(uint64_t fromVersion = 0); - void readUpdate(ByteArray data); + pair writeUpdate(uint64_t fromVersion = 0, NetCompatibilityRules rules = {}); + void readUpdate(ByteArray data, NetCompatibilityRules rules = {}); // handles flying and warp state transitions void stateUpdate(); diff --git a/source/game/StarStagehand.cpp b/source/game/StarStagehand.cpp index 83b7673..d85f77b 100644 --- a/source/game/StarStagehand.cpp +++ b/source/game/StarStagehand.cpp @@ -14,8 +14,7 @@ Stagehand::Stagehand(Json const& config) readConfig(config); } -Stagehand::Stagehand(ByteArray const& netStore) - : Stagehand() { +Stagehand::Stagehand(ByteArray const& netStore, NetCompatibilityRules rules) : Stagehand() { readConfig(DataStreamBuffer::deserialize(netStore)); } @@ -31,7 +30,7 @@ Json Stagehand::diskStore() const { return saveData.set("scriptStorage", m_scriptComponent.getScriptStorage()); } -ByteArray Stagehand::netStore() { +ByteArray Stagehand::netStore(NetCompatibilityRules rules) { return DataStreamBuffer::serialize(m_config); } @@ -77,12 +76,12 @@ RectF Stagehand::metaBoundBox() const { return m_boundBox; } -pair Stagehand::writeNetState(uint64_t fromVersion) { - return m_netGroup.writeNetState(fromVersion); +pair Stagehand::writeNetState(uint64_t fromVersion, NetCompatibilityRules rules) { + return m_netGroup.writeNetState(fromVersion, rules); } -void Stagehand::readNetState(ByteArray data, float) { - m_netGroup.readNetState(std::move(data)); +void Stagehand::readNetState(ByteArray data, float interpolationTime, NetCompatibilityRules rules) { + m_netGroup.readNetState(data, interpolationTime, rules); } void Stagehand::update(float dt, uint64_t) { diff --git a/source/game/StarStagehand.hpp b/source/game/StarStagehand.hpp index 4297370..4403946 100644 --- a/source/game/StarStagehand.hpp +++ b/source/game/StarStagehand.hpp @@ -15,10 +15,10 @@ STAR_CLASS(Stagehand); class Stagehand : public virtual ScriptedEntity { public: Stagehand(Json const& config); - Stagehand(ByteArray const& netStore); + Stagehand(ByteArray const& netStore, NetCompatibilityRules rules = {}); Json diskStore() const; - ByteArray netStore(); + ByteArray netStore(NetCompatibilityRules rules = {}); void init(World* world, EntityId entityId, EntityMode mode) override; void uninit() override; @@ -31,8 +31,8 @@ public: RectF metaBoundBox() const override; - pair writeNetState(uint64_t fromVersion = 0) override; - void readNetState(ByteArray data, float interpolationTime = 0.0f) override; + pair writeNetState(uint64_t fromVersion = 0, NetCompatibilityRules rules = {}) override; + void readNetState(ByteArray data, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; void update(float dt, uint64_t currentStep) override; diff --git a/source/game/StarStatusController.cpp b/source/game/StarStatusController.cpp index 5a87874..a2a5e9c 100644 --- a/source/game/StarStatusController.cpp +++ b/source/game/StarStatusController.cpp @@ -18,7 +18,32 @@ StatusController::StatusController(Json const& config) : m_statCollection(config m_parentEntity = nullptr; m_movementController = nullptr; - m_statusProperties.set(config.getObject("statusProperties", {})); + m_statusProperties.reset(config.getObject("statusProperties", {})); + m_statusProperties.setOverrides( + [&](DataStream& ds, NetCompatibilityRules rules) { + if (rules.isLegacy) ds << m_statusProperties.baseMap(); + else m_statusProperties.NetElementHashMap::netStore(ds, rules); + }, + [&](DataStream& ds, NetCompatibilityRules rules) { + if (rules.isLegacy) m_statusProperties.reset(ds.read()); + else m_statusProperties.NetElementHashMap::netLoad(ds, rules); + }, + [&](DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules) { + if (rules.isLegacy) { + if (m_statusProperties.shouldWriteNetDelta(fromVersion, rules)) { + ds << m_statusProperties.baseMap(); + return true; + } + return false; + } + return m_statusProperties.NetElementHashMap::writeNetDelta(ds, fromVersion, rules); + }, + [&](DataStream& ds, float interp, NetCompatibilityRules rules) { + if (rules.isLegacy) m_statusProperties.reset(ds.read()); + else m_statusProperties.NetElementHashMap::readNetDelta(ds, interp, rules); + } + ); + m_minimumLiquidStatusEffectPercentage = config.getFloat("minimumLiquidStatusEffectPercentage"); m_appliesEnvironmentStatusEffects = config.getBool("appliesEnvironmentStatusEffects"); m_appliesWeatherStatusEffects = config.getBool("appliesWeatherStatusEffects"); @@ -72,7 +97,7 @@ Json StatusController::diskStore() const { } return JsonObject{ - {"statusProperties", m_statusProperties.get()}, + {"statusProperties", m_statusProperties.baseMap()}, {"persistentEffectCategories", std::move(persistentEffectCategories)}, {"ephemeralEffects", std::move(ephemeralEffects)}, {"resourceValues", std::move(resourceValues)}, @@ -84,7 +109,7 @@ void StatusController::diskLoad(Json const& store) { clearAllPersistentEffects(); clearEphemeralEffects(); - m_statusProperties.set(store.getObject("statusProperties")); + m_statusProperties.reset(store.getObject("statusProperties")); for (auto const& p : store.getObject("persistentEffectCategories", {})) addPersistentEffects(p.first, p.second.toArray().transformed(jsonToPersistentStatusEffect)); @@ -103,17 +128,11 @@ void StatusController::diskLoad(Json const& store) { } Json StatusController::statusProperty(String const& name, Json const& def) const { - return m_statusProperties.get().value(name, def); + return m_statusProperties.value(name, def); } void StatusController::setStatusProperty(String const& name, Json value) { - m_statusProperties.update([&](JsonObject& statusProperties) { - if (statusProperties[name] != value) { - statusProperties[name] = std::move(value); - return true; - } - return false; - }); + m_statusProperties.set(name, value); } StringList StatusController::statNames() const { @@ -415,15 +434,17 @@ void StatusController::initNetVersion(NetElementVersion const* version) { m_netGroup.initNetVersion(version); } -void StatusController::netStore(DataStream& ds) const { - m_netGroup.netStore(ds); +void StatusController::netStore(DataStream& ds, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return; + m_netGroup.netStore(ds, rules); } -void StatusController::netLoad(DataStream& ds) { +void StatusController::netLoad(DataStream& ds, NetCompatibilityRules rules) { + if (!checkWithRules(rules)) return; clearAllPersistentEffects(); clearEphemeralEffects(); - m_netGroup.netLoad(ds); + m_netGroup.netLoad(ds, rules); } void StatusController::enableNetInterpolation(float extrapolationHint) { @@ -438,12 +459,12 @@ void StatusController::tickNetInterpolation(float dt) { m_netGroup.tickNetInterpolation(dt); } -bool StatusController::writeNetDelta(DataStream& ds, uint64_t fromStep) const { - return m_netGroup.writeNetDelta(ds, fromStep); +bool StatusController::writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules) const { + return m_netGroup.writeNetDelta(ds, fromVersion, rules); } -void StatusController::readNetDelta(DataStream& ds, float interpolationTime) { - m_netGroup.readNetDelta(ds, interpolationTime); +void StatusController::readNetDelta(DataStream& ds, float interpolationTime, NetCompatibilityRules rules) { + m_netGroup.readNetDelta(ds, interpolationTime, rules); } void StatusController::blankNetDelta(float interpolationTime) { @@ -576,15 +597,17 @@ void StatusController::EffectAnimator::initNetVersion(NetElementVersion const* v animator.initNetVersion(version); } -void StatusController::EffectAnimator::netStore(DataStream& ds) const { +void StatusController::EffectAnimator::netStore(DataStream& ds, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return; ds.write(animationConfig); - animator.netStore(ds); + animator.netStore(ds, rules); } -void StatusController::EffectAnimator::netLoad(DataStream& ds) { +void StatusController::EffectAnimator::netLoad(DataStream& ds, NetCompatibilityRules rules) { + if (!checkWithRules(rules)) return; ds.read(animationConfig); animator = animationConfig ? NetworkedAnimator(*animationConfig) : NetworkedAnimator(); - animator.netLoad(ds); + animator.netLoad(ds, rules); } void StatusController::EffectAnimator::enableNetInterpolation(float extrapolationHint) { @@ -599,12 +622,12 @@ void StatusController::EffectAnimator::tickNetInterpolation(float dt) { animator.tickNetInterpolation(dt); } -bool StatusController::EffectAnimator::writeNetDelta(DataStream& ds, uint64_t fromVersion) const { - return animator.writeNetDelta(ds, fromVersion); +bool StatusController::EffectAnimator::writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules) const { + return animator.writeNetDelta(ds, fromVersion, rules); } -void StatusController::EffectAnimator::readNetDelta(DataStream& ds, float interpolationTime) { - animator.readNetDelta(ds, interpolationTime); +void StatusController::EffectAnimator::readNetDelta(DataStream& ds, float interpolationTime, NetCompatibilityRules rules) { + animator.readNetDelta(ds, interpolationTime, rules); } void StatusController::EffectAnimator::blankNetDelta(float interpolationTime) { diff --git a/source/game/StarStatusController.hpp b/source/game/StarStatusController.hpp index 810a2c9..039cc3b 100644 --- a/source/game/StarStatusController.hpp +++ b/source/game/StarStatusController.hpp @@ -2,6 +2,7 @@ #include "StarObserverStream.hpp" #include "StarNetElementSystem.hpp" +#include "StarNetElementExt.hpp" #include "StarStatCollection.hpp" #include "StarStatusEffectDatabase.hpp" #include "StarDamage.hpp" @@ -103,15 +104,15 @@ public: void initNetVersion(NetElementVersion const* version = nullptr) override; - void netStore(DataStream& ds) const override; - void netLoad(DataStream& ds) override; + void netStore(DataStream& ds, NetCompatibilityRules rules = {}) const override; + void netLoad(DataStream& ds, NetCompatibilityRules rules) override; void enableNetInterpolation(float extrapolationHint = 0.0f) override; void disableNetInterpolation() override; void tickNetInterpolation(float dt) override; - bool writeNetDelta(DataStream& ds, uint64_t fromVersion) const override; - void readNetDelta(DataStream& ds, float interpolationTime = 0.0) override; + bool writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules = {}) const override; + void readNetDelta(DataStream& ds, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; void blankNetDelta(float interpolationTime) override; void tickMaster(float dt); @@ -136,15 +137,15 @@ private: void initNetVersion(NetElementVersion const* version = nullptr) override; - void netStore(DataStream& ds) const override; - void netLoad(DataStream& ds) override; + void netStore(DataStream& ds, NetCompatibilityRules rules = {}) const override; + void netLoad(DataStream& ds, NetCompatibilityRules rules) override; void enableNetInterpolation(float extrapolationHint = 0.0f) override; void disableNetInterpolation() override; void tickNetInterpolation(float dt) override; - bool writeNetDelta(DataStream& ds, uint64_t fromVersion) const override; - void readNetDelta(DataStream& ds, float interpolationTime = 0.0) override; + bool writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules = {}) const override; + void readNetDelta(DataStream& ds, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; void blankNetDelta(float interpolationTime) override; Maybe animationConfig; @@ -203,7 +204,7 @@ private: NetElementGroup m_netGroup; StatCollection m_statCollection; - NetElementData m_statusProperties; + NetElementOverride> m_statusProperties; NetElementData m_parentDirectives; UniqueEffectMetadataGroup m_uniqueEffectMetadata; diff --git a/source/game/StarSystemWorld.cpp b/source/game/StarSystemWorld.cpp index c7e1213..9823b8f 100644 --- a/source/game/StarSystemWorld.cpp +++ b/source/game/StarSystemWorld.cpp @@ -453,12 +453,12 @@ void SystemObject::serverUpdate(SystemWorldServer* system, float dt) { } } -pair SystemObject::writeNetState(uint64_t fromVersion) { - return m_netGroup.writeNetState(fromVersion); +pair SystemObject::writeNetState(uint64_t fromVersion, NetCompatibilityRules rules) { + return m_netGroup.writeNetState(fromVersion, rules); } -void SystemObject::readNetState(ByteArray data, float interpolationTime) { - m_netGroup.readNetState(std::move(data), interpolationTime); +void SystemObject::readNetState(ByteArray data, float interpolationTime, NetCompatibilityRules rules) { + m_netGroup.readNetState(data, interpolationTime, rules); } ByteArray SystemObject::netStore() const { @@ -615,12 +615,12 @@ void SystemClientShip::serverUpdate(SystemWorld* system, float dt) { } } -pair SystemClientShip::writeNetState(uint64_t fromVersion) { - return m_netGroup.writeNetState(fromVersion); +pair SystemClientShip::writeNetState(uint64_t fromVersion, NetCompatibilityRules rules) { + return m_netGroup.writeNetState(fromVersion, rules); } -void SystemClientShip::readNetState(ByteArray data, float interpolationTime) { - m_netGroup.readNetState(std::move(data), interpolationTime); +void SystemClientShip::readNetState(ByteArray data, float interpolationTime, NetCompatibilityRules rules) { + m_netGroup.readNetState(data, interpolationTime, rules); } ByteArray SystemClientShip::netStore() const { diff --git a/source/game/StarSystemWorld.hpp b/source/game/StarSystemWorld.hpp index db12833..cde3323 100644 --- a/source/game/StarSystemWorld.hpp +++ b/source/game/StarSystemWorld.hpp @@ -155,8 +155,8 @@ public: void clientUpdate(float dt); void serverUpdate(SystemWorldServer* system, float dt); - pair writeNetState(uint64_t fromVersion); - void readNetState(ByteArray data, float interpolationTime); + pair writeNetState(uint64_t fromVersion, NetCompatibilityRules rules = {}); + void readNetState(ByteArray data, float interpolationTime, NetCompatibilityRules rules = {}); ByteArray netStore() const; Json diskStore() const; @@ -198,8 +198,8 @@ public: void clientUpdate(float dt); void serverUpdate(SystemWorld* system, float dt); - pair writeNetState(uint64_t fromVersion); - void readNetState(ByteArray data, float interpolationTime); + pair writeNetState(uint64_t fromVersion, NetCompatibilityRules rules = {}); + void readNetState(ByteArray data, float interpolationTime, NetCompatibilityRules rules = {}); ByteArray netStore() const; private: diff --git a/source/game/StarSystemWorldServer.cpp b/source/game/StarSystemWorldServer.cpp index 3b847eb..201b90b 100644 --- a/source/game/StarSystemWorldServer.cpp +++ b/source/game/StarSystemWorldServer.cpp @@ -266,7 +266,7 @@ void SystemWorldServer::queueUpdatePackets() { HashMap shipUpdates; for (auto ship : m_ships.values()) { uint64_t version = versions->ships.maybe(ship->uuid()).value(0); - auto shipUpdate = ship->writeNetState(version); + auto shipUpdate = ship->writeNetState(version, {}); versions->ships.set(ship->uuid(), shipUpdate.second); if (!shipUpdate.first.empty()) shipUpdates.set(ship->uuid(), shipUpdate.first); @@ -275,7 +275,7 @@ void SystemWorldServer::queueUpdatePackets() { HashMap objectUpdates; for (auto object : m_objects.values()) { uint64_t version = versions->objects.maybe(object->uuid()).value(0); - auto objectUpdate = object->writeNetState(version); + auto objectUpdate = object->writeNetState(version, {}); versions->objects.set(object->uuid(), objectUpdate.second); if (!objectUpdate.first.empty()) objectUpdates.set(object->uuid(), objectUpdate.first); diff --git a/source/game/StarTechController.cpp b/source/game/StarTechController.cpp index 90926de..4c0ed55 100644 --- a/source/game/StarTechController.cpp +++ b/source/game/StarTechController.cpp @@ -358,15 +358,17 @@ void TechController::TechAnimator::initNetVersion(NetElementVersion const* versi netGroup.initNetVersion(version); } -void TechController::TechAnimator::netStore(DataStream& ds) const { +void TechController::TechAnimator::netStore(DataStream& ds, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return; ds << animationConfig; - netGroup.netStore(ds); + netGroup.netStore(ds, rules); } -void TechController::TechAnimator::netLoad(DataStream& ds) { +void TechController::TechAnimator::netLoad(DataStream& ds, NetCompatibilityRules rules) { + if (!checkWithRules(rules)) return; ds >> animationConfig; animator = animationConfig ? NetworkedAnimator(*animationConfig) : NetworkedAnimator(); - netGroup.netLoad(ds); + netGroup.netLoad(ds, rules); } void TechController::TechAnimator::enableNetInterpolation(float extrapolationHint) { @@ -381,12 +383,12 @@ void TechController::TechAnimator::tickNetInterpolation(float dt) { netGroup.tickNetInterpolation(dt); } -bool TechController::TechAnimator::writeNetDelta(DataStream& ds, uint64_t fromVersion) const { - return netGroup.writeNetDelta(ds, fromVersion); +bool TechController::TechAnimator::writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules) const { + return netGroup.writeNetDelta(ds, fromVersion, rules); } -void TechController::TechAnimator::readNetDelta(DataStream& ds, float interpolationTime) { - netGroup.readNetDelta(ds, interpolationTime); +void TechController::TechAnimator::readNetDelta(DataStream& ds, float interpolationTime, NetCompatibilityRules rules) { + netGroup.readNetDelta(ds, interpolationTime, rules); } void TechController::TechAnimator::blankNetDelta(float interpolationTime) { diff --git a/source/game/StarTechController.hpp b/source/game/StarTechController.hpp index 3d642df..c399cb5 100644 --- a/source/game/StarTechController.hpp +++ b/source/game/StarTechController.hpp @@ -90,15 +90,15 @@ private: void initNetVersion(NetElementVersion const* version = nullptr) override; - void netStore(DataStream& ds) const override; - void netLoad(DataStream& ds) override; + void netStore(DataStream& ds, NetCompatibilityRules rules = {}) const override; + void netLoad(DataStream& ds, NetCompatibilityRules rules) override; void enableNetInterpolation(float extrapolationHint = 0.0f) override; void disableNetInterpolation() override; void tickNetInterpolation(float dt) override; - bool writeNetDelta(DataStream& ds, uint64_t fromVersion) const override; - void readNetDelta(DataStream& ds, float interpolationTime = 0.0) override; + bool writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules = {}) const override; + void readNetDelta(DataStream& ds, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; void blankNetDelta(float interpolationTime) override; // If setting invisible, stops all playing audio diff --git a/source/game/StarToolUser.cpp b/source/game/StarToolUser.cpp index 4135dd0..be239c1 100644 --- a/source/game/StarToolUser.cpp +++ b/source/game/StarToolUser.cpp @@ -612,15 +612,17 @@ void ToolUser::NetItem::initNetVersion(NetElementVersion const* version) { netItem->initNetVersion(m_netVersion); } -void ToolUser::NetItem::netStore(DataStream& ds) const { +void ToolUser::NetItem::netStore(DataStream& ds, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return; const_cast(this)->updateItemDescriptor(); - m_itemDescriptor.netStore(ds); + m_itemDescriptor.netStore(ds, rules); if (auto netItem = as(m_item.get())) - netItem->netStore(ds); + netItem->netStore(ds, rules); } -void ToolUser::NetItem::netLoad(DataStream& ds) { - m_itemDescriptor.netLoad(ds); +void ToolUser::NetItem::netLoad(DataStream& ds, NetCompatibilityRules rules) { + if (!checkWithRules(rules)) return; + m_itemDescriptor.netLoad(ds, rules); auto itemDatabase = Root::singleton().itemDatabase(); if (itemDatabase->loadItem(m_itemDescriptor.get(), m_item)) { @@ -633,7 +635,7 @@ void ToolUser::NetItem::netLoad(DataStream& ds) { } if (auto netItem = as(m_item.get())) - netItem->netLoad(ds); + netItem->netLoad(ds, rules); } void ToolUser::NetItem::enableNetInterpolation(float extrapolationHint) { @@ -657,23 +659,24 @@ void ToolUser::NetItem::tickNetInterpolation(float dt) { } } -bool ToolUser::NetItem::writeNetDelta(DataStream& ds, uint64_t fromVersion) const { +bool ToolUser::NetItem::writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules) const { + if (!checkWithRules(rules)) return false; bool deltaWritten = false; const_cast(this)->updateItemDescriptor(); m_buffer.clear(); - if (m_itemDescriptor.writeNetDelta(m_buffer, fromVersion)) { + if (m_itemDescriptor.writeNetDelta(m_buffer, fromVersion, rules)) { deltaWritten = true; ds.write(1); ds.writeBytes(m_buffer.data()); if (auto netItem = as(m_item.get())) { ds.write(2); - netItem->netStore(ds); + netItem->netStore(ds, rules); } } if (auto netItem = as(m_item.get())) { m_buffer.clear(); - if (netItem->writeNetDelta(m_buffer, fromVersion)) { + if (netItem->writeNetDelta(m_buffer, fromVersion, rules)) { deltaWritten = true; ds.write(3); ds.writeBytes(m_buffer.data()); @@ -685,13 +688,14 @@ bool ToolUser::NetItem::writeNetDelta(DataStream& ds, uint64_t fromVersion) cons return deltaWritten; } -void ToolUser::NetItem::readNetDelta(DataStream& ds, float interpolationTime) { +void ToolUser::NetItem::readNetDelta(DataStream& ds, float interpolationTime, NetCompatibilityRules rules) { + if (!checkWithRules(rules)) return; while (true) { uint8_t code = ds.read(); if (code == 0) { break; } else if (code == 1) { - m_itemDescriptor.readNetDelta(ds); + m_itemDescriptor.readNetDelta(ds, 0.0f, rules); if (!m_item || !m_item->matches(m_itemDescriptor.get(), true)) { auto itemDatabase = Root::singleton().itemDatabase(); if (itemDatabase->loadItem(m_itemDescriptor.get(), m_item)) { @@ -705,12 +709,12 @@ void ToolUser::NetItem::readNetDelta(DataStream& ds, float interpolationTime) { } } else if (code == 2) { if (auto netItem = as(m_item.get())) - netItem->netLoad(ds); + netItem->netLoad(ds, rules); else throw IOException("Server/Client disagreement about whether an Item is a NetElement in NetItem::readNetDelta"); } else if (code == 3) { if (auto netItem = as(m_item.get())) - netItem->readNetDelta(ds, interpolationTime); + netItem->readNetDelta(ds, interpolationTime, rules); else throw IOException("Server/Client disagreement about whether an Item is a NetElement in NetItem::readNetDelta"); } else { diff --git a/source/game/StarToolUser.hpp b/source/game/StarToolUser.hpp index 41fe98f..0b954e2 100644 --- a/source/game/StarToolUser.hpp +++ b/source/game/StarToolUser.hpp @@ -81,15 +81,15 @@ private: public: void initNetVersion(NetElementVersion const* version = nullptr) override; - void netStore(DataStream& ds) const override; - void netLoad(DataStream& ds) override; + void netStore(DataStream& ds, NetCompatibilityRules rules = {}) const override; + void netLoad(DataStream& ds, NetCompatibilityRules rules) override; void enableNetInterpolation(float extrapolationHint = 0.0f) override; void disableNetInterpolation() override; void tickNetInterpolation(float dt) override; - bool writeNetDelta(DataStream& ds, uint64_t fromVersion) const override; - void readNetDelta(DataStream& ds, float interpolationTime = 0.0) override; + bool writeNetDelta(DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules = {}) const override; + void readNetDelta(DataStream& ds, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; void blankNetDelta(float interpolationTime) override; ItemPtr const& get() const; diff --git a/source/game/StarUniverseClient.cpp b/source/game/StarUniverseClient.cpp index ed59c4b..023140c 100644 --- a/source/game/StarUniverseClient.cpp +++ b/source/game/StarUniverseClient.cpp @@ -94,7 +94,8 @@ Maybe UniverseClient::connect(UniverseConnection connection, bool allowA else if (!protocolResponsePacket->allowed) return String(strf("Join failed! Server does not support connections with protocol version {}", StarProtocolVersion)); - if (!(m_legacyServer = protocolResponsePacket->compressionMode() != PacketCompressionMode::Enabled)) { + bool legacyServer = protocolResponsePacket->compressionMode() != PacketCompressionMode::Enabled; + if (!legacyServer) { if (auto compressedSocket = as(&connection.packetSocket())) { if (protocolResponsePacket->info) { auto compressionName = protocolResponsePacket->info.getString("compression", "None"); @@ -104,13 +105,13 @@ Maybe UniverseClient::connect(UniverseConnection connection, bool allowA Logger::info("UniverseClient: Using '{}' network stream compression", NetCompressionModeNames.getRight(*compressionMode)); compressedSocket->setCompressionStreamEnabled(compressionMode == NetCompressionMode::Zstd); - } else if (!m_legacyServer) { + } else { Logger::info("UniverseClient: Defaulting to Zstd network stream compression (older server version)"); compressedSocket->setCompressionStreamEnabled(true);// old OpenSB server version always expects it! } } } - connection.packetSocket().setLegacy(m_legacyServer); + connection.packetSocket().setLegacy(legacyServer); 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); @@ -133,14 +134,18 @@ Maybe UniverseClient::connect(UniverseConnection connection, bool allowA packet = connection.pullSingle(); } + NetCompatibilityRules compatibilityRules; + compatibilityRules.isLegacy = legacyServer; + if (auto success = as(packet)) { m_universeClock = make_shared(); m_clientContext = make_shared(success->serverUuid, m_mainPlayer->uuid()); + m_clientContext->setNetCompatibilityRules(compatibilityRules); m_teamClient = make_shared(m_mainPlayer, m_clientContext); m_mainPlayer->setClientContext(m_clientContext); m_mainPlayer->setStatistics(m_statistics); m_worldClient = make_shared(m_mainPlayer); - m_worldClient->clientState().setLegacy(m_legacyServer); + m_worldClient->clientState().setNetCompatibilityRules(compatibilityRules); m_worldClient->setAsyncLighting(true); for (auto& pair : m_luaCallbacks) m_worldClient->setLuaCallbacks(pair.first, pair.second); @@ -149,7 +154,7 @@ Maybe UniverseClient::connect(UniverseConnection connection, bool allowA m_celestialDatabase = make_shared(std::move(success->celestialInformation)); m_systemWorldClient = make_shared(m_universeClock, m_celestialDatabase, m_mainPlayer->universeMap()); - Logger::info("UniverseClient: Joined {} server as client {}", m_legacyServer ? "Starbound" : "OpenStarbound", success->clientId); + Logger::info("UniverseClient: Joined {} server as client {}", legacyServer ? "Starbound" : "OpenStarbound", success->clientId); return {}; } else if (auto failure = as(packet)) { Logger::error("UniverseClient: Join failed: {}", failure->reason); @@ -263,7 +268,7 @@ void UniverseClient::update(float dt) { m_teamClient->update(); - auto contextUpdate = m_clientContext->writeUpdate(); + auto contextUpdate = m_clientContext->writeUpdate(m_clientContext->netCompatibilityRules()); if (!contextUpdate.empty()) m_connection->pushSingle(make_shared(std::move(contextUpdate))); @@ -650,7 +655,7 @@ void UniverseClient::handlePackets(List const& packets) { for (auto const& packet : packets) { try { if (auto clientContextUpdate = as(packet)) { - m_clientContext->readUpdate(clientContextUpdate->updateData); + m_clientContext->readUpdate(clientContextUpdate->updateData, m_clientContext->netCompatibilityRules()); m_playerStorage->applyShipUpdates(m_clientContext->playerUuid(), m_clientContext->newShipUpdates()); if (playerIsOriginal()) diff --git a/source/game/StarUniverseClient.hpp b/source/game/StarUniverseClient.hpp index 985124a..6a85cdb 100644 --- a/source/game/StarUniverseClient.hpp +++ b/source/game/StarUniverseClient.hpp @@ -126,7 +126,6 @@ private: StatisticsPtr m_statistics; PlayerPtr m_mainPlayer; - bool m_legacyServer; bool m_pause; ClockPtr m_universeClock; WorldClientPtr m_worldClient; diff --git a/source/game/StarUniverseServer.cpp b/source/game/StarUniverseServer.cpp index 28f7862..09cfdc8 100644 --- a/source/game/StarUniverseServer.cpp +++ b/source/game/StarUniverseServer.cpp @@ -835,7 +835,10 @@ void UniverseServer::warpPlayers() { // Checking the spawn target validity then adding the client is not // perfect, it can still become invalid in between, if we fail at // adding the client we need to warp them back. - if (toWorld && toWorld->addClient(clientId, warpToWorld.target, !clientContext->remoteAddress(), clientContext->canBecomeAdmin())) { + if (toWorld && toWorld->addClient(clientId, warpToWorld.target, + !clientContext->remoteAddress(), + clientContext->canBecomeAdmin(), + clientContext->netRules())) { clientContext->setPlayerWorld(toWorld); m_chatProcessor->joinChannel(clientId, printWorldId(warpToWorld.world)); @@ -1698,7 +1701,8 @@ void UniverseServer::acceptConnection(UniverseConnection connection, Maybe(clientId, remoteAddress, clientConnect->playerUuid, + NetCompatibilityRules netRules(legacyClient); + auto clientContext = make_shared(clientId, remoteAddress, netRules, clientConnect->playerUuid, clientConnect->playerName, clientConnect->playerSpecies, administrator, clientConnect->shipChunks); m_clients.add(clientId, clientContext); m_connectionServer->addConnection(clientId, std::move(connection)); diff --git a/source/game/StarVehicle.cpp b/source/game/StarVehicle.cpp index 0aec750..29a57b0 100644 --- a/source/game/StarVehicle.cpp +++ b/source/game/StarVehicle.cpp @@ -242,12 +242,12 @@ Vec2F Vehicle::velocity() const { return m_movementController.velocity(); } -pair Vehicle::writeNetState(uint64_t fromVersion) { - return m_netGroup.writeNetState(fromVersion); +pair Vehicle::writeNetState(uint64_t fromVersion, NetCompatibilityRules rules) { + return m_netGroup.writeNetState(fromVersion, rules); } -void Vehicle::readNetState(ByteArray data, float interpolationTime) { - m_netGroup.readNetState(std::move(data), interpolationTime); +void Vehicle::readNetState(ByteArray data, float interpolationTime, NetCompatibilityRules rules) { + m_netGroup.readNetState(data, interpolationTime, rules); } void Vehicle::enableInterpolation(float extrapolationHint) { diff --git a/source/game/StarVehicle.hpp b/source/game/StarVehicle.hpp index b70d4ae..087137f 100644 --- a/source/game/StarVehicle.hpp +++ b/source/game/StarVehicle.hpp @@ -44,8 +44,8 @@ public: RectF collisionArea() const override; Vec2F velocity() const; - pair writeNetState(uint64_t fromVersion) override; - void readNetState(ByteArray data, float interpolationTime = 0) override; + pair writeNetState(uint64_t fromVersion = 0, NetCompatibilityRules rules = {}) override; + void readNetState(ByteArray data, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}) override; void enableInterpolation(float extrapolationHint) override; void disableInterpolation() override; diff --git a/source/game/StarVehicleDatabase.cpp b/source/game/StarVehicleDatabase.cpp index 370aceb..a8739fa 100644 --- a/source/game/StarVehicleDatabase.cpp +++ b/source/game/StarVehicleDatabase.cpp @@ -10,7 +10,7 @@ VehicleDatabase::VehicleDatabase() { auto assets = Root::singleton().assets(); auto& files = assets->scanExtension("vehicle"); assets->queueJsons(files); - for (auto& file : files) { + for (String file : files) { try { auto config = assets->json(file); String name = config.getString("name"); @@ -32,15 +32,18 @@ VehiclePtr VehicleDatabase::create(String const& vehicleName, Json const& extraC return make_shared(configPair->second, configPair->first, extraConfig); } -ByteArray VehicleDatabase::netStore(VehiclePtr const& vehicle) const { +ByteArray VehicleDatabase::netStore(VehiclePtr const& vehicle, NetCompatibilityRules rules) const { DataStreamBuffer ds; + ds.setStreamCompatibilityVersion(rules); + ds.write(vehicle->baseConfig().getString("name")); ds.write(vehicle->dynamicConfig()); return ds.takeData(); } -VehiclePtr VehicleDatabase::netLoad(ByteArray const& netStore) const { +VehiclePtr VehicleDatabase::netLoad(ByteArray const& netStore, NetCompatibilityRules rules) const { DataStreamBuffer ds(netStore); + ds.setStreamCompatibilityVersion(rules); String name = ds.read(); auto dynamicConfig = ds.read(); diff --git a/source/game/StarVehicleDatabase.hpp b/source/game/StarVehicleDatabase.hpp index ba7bf7c..ed90a7d 100644 --- a/source/game/StarVehicleDatabase.hpp +++ b/source/game/StarVehicleDatabase.hpp @@ -13,8 +13,8 @@ public: VehiclePtr create(String const& vehicleName, Json const& extraConfig = Json()) const; - ByteArray netStore(VehiclePtr const& vehicle) const; - VehiclePtr netLoad(ByteArray const& netStore) const; + ByteArray netStore(VehiclePtr const& vehicle, NetCompatibilityRules rules) const; + VehiclePtr netLoad(ByteArray const& netStore, NetCompatibilityRules rules) const; Json diskStore(VehiclePtr const& vehicle) const; VehiclePtr diskLoad(Json const& diskStore) const; diff --git a/source/game/StarWeather.cpp b/source/game/StarWeather.cpp index 6b1c6a7..6fe1a53 100644 --- a/source/game/StarWeather.cpp +++ b/source/game/StarWeather.cpp @@ -55,9 +55,9 @@ void ServerWeather::setClientVisibleRegions(List regions) { m_clientVisibleRegions = std::move(regions); } -pair ServerWeather::writeUpdate(uint64_t fromVersion) { +pair ServerWeather::writeUpdate(uint64_t fromVersion, NetCompatibilityRules rules) { setNetStates(); - return m_netGroup.writeNetState(fromVersion); + return m_netGroup.writeNetState(fromVersion, rules); } void ServerWeather::update(double dt) { @@ -263,9 +263,9 @@ void ClientWeather::setup(WorldGeometry worldGeometry, WeatherEffectsActiveQuery m_currentTime = 0.0; } -void ClientWeather::readUpdate(ByteArray data) { +void ClientWeather::readUpdate(ByteArray data, NetCompatibilityRules rules) { if (!data.empty()) { - m_netGroup.readNetState(std::move(data)); + m_netGroup.readNetState(data, 0.0f, rules); getNetStates(); } } diff --git a/source/game/StarWeather.hpp b/source/game/StarWeather.hpp index 7d699ea..4bde334 100644 --- a/source/game/StarWeather.hpp +++ b/source/game/StarWeather.hpp @@ -29,7 +29,7 @@ public: void setClientVisibleRegions(List regions); - pair writeUpdate(uint64_t fromVersion = 0); + pair writeUpdate(uint64_t fromVersion = 0, NetCompatibilityRules rules = {}); void update(double dt); @@ -80,7 +80,7 @@ public: void setup(WorldGeometry worldGeometry, WeatherEffectsActiveQuery weatherEffectsActiveQuery); - void readUpdate(ByteArray data); + void readUpdate(ByteArray data, NetCompatibilityRules rules); void setVisibleRegion(RectI visibleRegion); diff --git a/source/game/StarWorldClient.cpp b/source/game/StarWorldClient.cpp index 9e0478a..aecb77a 100644 --- a/source/game/StarWorldClient.cpp +++ b/source/game/StarWorldClient.cpp @@ -168,7 +168,8 @@ void WorldClient::removeEntity(EntityId entityId, bool andDie) { } if (auto version = m_masterEntitiesNetVersion.maybeTake(entity->entityId())) { - ByteArray finalNetState = entity->writeNetState(*version).first; + auto netRules = m_clientState.netCompatibilityRules(); + ByteArray finalNetState = entity->writeNetState(*version, netRules).first; m_outgoingPackets.append(make_shared(entity->entityId(), std::move(finalNetState), andDie)); } @@ -767,7 +768,7 @@ void WorldClient::handleIncomingPackets(List const& packets) { } auto entity = entityFactory->netLoadEntity(entityCreate->entityType, entityCreate->storeData); - entity->readNetState(entityCreate->firstNetState); + entity->readNetState(entityCreate->firstNetState, 0.0f, m_clientState.netCompatibilityRules()); entity->init(this, entityCreate->entityId, EntityMode::Slave); m_entityMap->addEntity(entity); @@ -788,13 +789,13 @@ void WorldClient::handleIncomingPackets(List const& packets) { EntityId entityId = entity->entityId(); if (connectionForEntity(entityId) == entityUpdateSet->forConnection) { starAssert(entity->isSlave()); - entity->readNetState(entityUpdateSet->deltas.value(entityId), interpolationLeadTime); + entity->readNetState(entityUpdateSet->deltas.value(entityId), interpolationLeadTime, m_clientState.netCompatibilityRules()); } }); } else if (auto entityDestroy = as(packet)) { if (auto entity = m_entityMap->entity(entityDestroy->entityId)) { - entity->readNetState(entityDestroy->finalNetState, m_interpolationTracker.interpolationLeadTime()); + entity->readNetState(entityDestroy->finalNetState, m_interpolationTracker.interpolationLeadTime(), m_clientState.netCompatibilityRules()); // Before destroying the entity, we should make sure that the entity is // using the absolute latest data, so we disable interpolation. @@ -909,8 +910,8 @@ void WorldClient::handleIncomingPackets(List const& packets) { m_interpolationTracker.receiveTimeUpdate(stepUpdate->remoteTime); } else if (auto environmentUpdatePacket = as(packet)) { - m_sky->readUpdate(environmentUpdatePacket->skyDelta); - m_weather.readUpdate(environmentUpdatePacket->weatherDelta); + m_sky->readUpdate(environmentUpdatePacket->skyDelta, m_clientState.netCompatibilityRules()); + m_weather.readUpdate(environmentUpdatePacket->weatherDelta, m_clientState.netCompatibilityRules()); } else if (auto hit = as(packet)) { m_damageManager->pushRemoteHitRequest(hit->remoteHitRequest); @@ -1229,7 +1230,7 @@ void WorldClient::update(float dt) { queueUpdatePackets(m_entityUpdateTimer.wrapTick(dt)); - if ((!m_clientState.legacy() && m_currentStep % 3 == 0) || m_pingTime.isNothing()) { + if ((!m_clientState.netCompatibilityRules().isLegacy && m_currentStep % 3 == 0) || m_pingTime.isNothing()) { m_pingTime = Time::monotonicMilliseconds(); m_outgoingPackets.append(make_shared(*m_pingTime)); } @@ -1325,7 +1326,8 @@ void WorldClient::addEntity(EntityPtr const& entity, EntityId entityId) { notifyEntityCreate(entity); } else { auto entityFactory = Root::singleton().entityFactory(); - m_outgoingPackets.append(make_shared(entity->entityType(), entityFactory->netStoreEntity(entity), entity->writeNetState().first)); + auto netRules = m_clientState.netCompatibilityRules(); + m_outgoingPackets.append(make_shared(entity->entityType(), entityFactory->netStoreEntity(entity), entity->writeNetState(0, netRules).first)); } } @@ -1456,9 +1458,10 @@ void WorldClient::queueUpdatePackets(bool sendEntityUpdates) { if (sendEntityUpdates) { auto entityUpdateSet = make_shared(); entityUpdateSet->forConnection = *m_clientId; + auto netRules = m_clientState.netCompatibilityRules(); m_entityMap->forAllEntities([&](EntityPtr const& entity) { if (auto version = m_masterEntitiesNetVersion.ptr(entity->entityId())) { - auto updateAndVersion = entity->writeNetState(*version); + auto updateAndVersion = entity->writeNetState(*version, netRules); if (!updateAndVersion.first.empty()) entityUpdateSet->deltas[entity->entityId()] = std::move(updateAndVersion.first); *version = updateAndVersion.second; @@ -1789,13 +1792,13 @@ void WorldClient::initWorld(WorldStartPacket const& startPacket) { centerClientWindowOnPlayer(); m_sky = make_shared(); - m_sky->readUpdate(startPacket.skyData); + m_sky->readUpdate(startPacket.skyData, m_clientState.netCompatibilityRules()); m_weather.setup(m_geometry, [this](Vec2I const& pos) { auto const& tile = m_tileArray->tile(pos); return !isRealMaterial(tile.background) && !isSolidColliding(tile.getCollision()); }); - m_weather.readUpdate(startPacket.weatherData); + m_weather.readUpdate(startPacket.weatherData, m_clientState.netCompatibilityRules()); m_lightingCalculator.setMonochrome(Root::singleton().configuration()->get("monochromeLighting").toBool()); m_lightingCalculator.setParameters(assets->json("/lighting.config:lighting")); @@ -1870,7 +1873,8 @@ void WorldClient::tryGiveMainPlayerItem(ItemPtr item, bool silent) { void WorldClient::notifyEntityCreate(EntityPtr const& entity) { if (entity->isMaster() && !m_masterEntitiesNetVersion.contains(entity->entityId())) { // Server was unaware of this entity until now - auto firstNetState = entity->writeNetState(); + auto netRules = m_clientState.netCompatibilityRules(); + auto firstNetState = entity->writeNetState(0, netRules); m_masterEntitiesNetVersion[entity->entityId()] = firstNetState.second; m_outgoingPackets.append(make_shared(entity->entityType(), Root::singleton().entityFactory()->netStoreEntity(entity), std::move(firstNetState.first), entity->entityId())); diff --git a/source/game/StarWorldClientState.cpp b/source/game/StarWorldClientState.cpp index 21552cd..4fbefc9 100644 --- a/source/game/StarWorldClientState.cpp +++ b/source/game/StarWorldClientState.cpp @@ -22,8 +22,6 @@ WorldClientState::WorldClientState() { m_netGroup.addNetElement(&m_playerId); m_netGroup.addNetElement(&m_clientPresenceEntities); - - m_legacy = false; } RectI WorldClientState::window() const { @@ -81,20 +79,20 @@ List WorldClientState::monitoringRegions(function(EntityId)> ByteArray WorldClientState::writeDelta() { ByteArray delta; - tie(delta, m_netVersion) = m_netGroup.writeNetState(m_netVersion); + tie(delta, m_netVersion) = m_netGroup.writeNetState(m_netVersion, m_netCompatibilityRules); return delta; } void WorldClientState::readDelta(ByteArray delta) { - m_netGroup.readNetState(std::move(delta)); + m_netGroup.readNetState(std::move(delta), 0.0f, m_netCompatibilityRules); } -void WorldClientState::setLegacy(bool legacy) { - m_legacy = legacy; +void WorldClientState::setNetCompatibilityRules(NetCompatibilityRules netCompatibilityRules) { + m_netCompatibilityRules = netCompatibilityRules; } -bool WorldClientState::legacy() const { - return m_legacy; +NetCompatibilityRules WorldClientState::netCompatibilityRules() const { + return m_netCompatibilityRules; } void WorldClientState::reset() { diff --git a/source/game/StarWorldClientState.hpp b/source/game/StarWorldClientState.hpp index 920fef4..746b7c5 100644 --- a/source/game/StarWorldClientState.hpp +++ b/source/game/StarWorldClientState.hpp @@ -36,9 +36,8 @@ public: ByteArray writeDelta(); void readDelta(ByteArray delta); - // Whether the client is connected to a legacy server. - void setLegacy(bool legacy); - bool legacy() const; + void setNetCompatibilityRules(NetCompatibilityRules netCompatibilityRules); + NetCompatibilityRules netCompatibilityRules() const; void reset(); @@ -57,7 +56,7 @@ private: NetElementInt m_playerId; NetElementData> m_clientPresenceEntities; - bool m_legacy; + NetCompatibilityRules m_netCompatibilityRules; }; } diff --git a/source/game/StarWorldServer.cpp b/source/game/StarWorldServer.cpp index a78025c..a2df77b 100644 --- a/source/game/StarWorldServer.cpp +++ b/source/game/StarWorldServer.cpp @@ -209,7 +209,7 @@ bool WorldServer::spawnTargetValid(SpawnTarget const& spawnTarget) const { return true; } -bool WorldServer::addClient(ConnectionId clientId, SpawnTarget const& spawnTarget, bool isLocal, bool isAdmin) { +bool WorldServer::addClient(ConnectionId clientId, SpawnTarget const& spawnTarget, bool isLocal, bool isAdmin, NetCompatibilityRules netRules) { if (m_clientInfo.contains(clientId)) return false; @@ -246,6 +246,7 @@ bool WorldServer::addClient(ConnectionId clientId, SpawnTarget const& spawnTarge auto& clientInfo = m_clientInfo.add(clientId, make_shared(clientId, tracker)); clientInfo->local = isLocal; clientInfo->admin = isAdmin; + clientInfo->clientState.setNetCompatibilityRules(netRules); auto worldStartPacket = make_shared(); auto& templateData = worldStartPacket->templateData = m_worldTemplate->store(); @@ -254,8 +255,8 @@ bool WorldServer::addClient(ConnectionId clientId, SpawnTarget const& spawnTarge && Root::singletonPtr()->configuration()->getPath("compatibility.customDungeonWorld").optBool().value(false)) worldStartPacket->templateData = worldStartPacket->templateData.setPath("worldParameters.primaryDungeon", "testarena"); - tie(worldStartPacket->skyData, clientInfo->skyNetVersion) = m_sky->writeUpdate(); - tie(worldStartPacket->weatherData, clientInfo->weatherNetVersion) = m_weather.writeUpdate(); + tie(worldStartPacket->skyData, clientInfo->skyNetVersion) = m_sky->writeUpdate(0, netRules); + tie(worldStartPacket->weatherData, clientInfo->weatherNetVersion) = m_weather.writeUpdate(0, netRules); worldStartPacket->playerStart = playerStart; worldStartPacket->playerRespawn = m_playerStart; worldStartPacket->respawnInWorld = m_respawnInWorld; @@ -381,7 +382,7 @@ void WorldServer::handleIncomingPackets(ConnectionId clientId, List c } else if (auto sepacket = as(packet)) { auto entity = entityFactory->netLoadEntity(sepacket->entityType, std::move(sepacket->storeData)); - entity->readNetState(std::move(sepacket->firstNetState)); + entity->readNetState(std::move(sepacket->firstNetState), 0.0f, clientInfo->clientState.netCompatibilityRules()); addEntity(std::move(entity)); } else if (auto rdpacket = as(packet)) { @@ -434,7 +435,7 @@ void WorldServer::handleIncomingPackets(ConnectionId clientId, List c } auto entity = entityFactory->netLoadEntity(entityCreate->entityType, entityCreate->storeData); - entity->readNetState(entityCreate->firstNetState); + entity->readNetState(entityCreate->firstNetState, 0.0f, clientInfo->clientState.netCompatibilityRules()); entity->init(this, entityCreate->entityId, EntityMode::Slave); m_entityMap->addEntity(entity); @@ -448,14 +449,14 @@ void WorldServer::handleIncomingPackets(ConnectionId clientId, List c EntityId entityId = entity->entityId(); if (connectionForEntity(entityId) == clientId) { starAssert(entity->isSlave()); - entity->readNetState(entityUpdateSet->deltas.value(entityId), interpolationLeadTime); + entity->readNetState(entityUpdateSet->deltas.value(entityId), interpolationLeadTime, clientInfo->clientState.netCompatibilityRules()); } }); clientInfo->pendingForward = true; } else if (auto entityDestroy = as(packet)) { if (auto entity = m_entityMap->entity(entityDestroy->entityId)) { - entity->readNetState(entityDestroy->finalNetState, clientInfo->interpolationTracker.interpolationLeadTime()); + entity->readNetState(entityDestroy->finalNetState, clientInfo->interpolationTracker.interpolationLeadTime(), clientInfo->clientState.netCompatibilityRules()); // Before destroying the entity, we should make sure that the entity is // using the absolute latest data, so we disable interpolation. entity->disableInterpolation(); @@ -691,6 +692,7 @@ void WorldServer::update(float dt) { queueUpdatePackets(pair.first, sendRemoteUpdates); } m_netStateCache.clear(); + m_legacyNetStateCache.clear(); for (auto& pair : m_clientInfo) pair.second->pendingForward = false; @@ -1789,10 +1791,10 @@ void WorldServer::queueUpdatePackets(ConnectionId clientId, bool sendRemoteUpdat if (shouldRunThisStep("environmentUpdate")) { ByteArray skyDelta; - tie(skyDelta, clientInfo->skyNetVersion) = m_sky->writeUpdate(clientInfo->skyNetVersion); + tie(skyDelta, clientInfo->skyNetVersion) = m_sky->writeUpdate(clientInfo->skyNetVersion, clientInfo->clientState.netCompatibilityRules()); ByteArray weatherDelta; - tie(weatherDelta, clientInfo->weatherNetVersion) = m_weather.writeUpdate(clientInfo->weatherNetVersion); + tie(weatherDelta, clientInfo->weatherNetVersion) = m_weather.writeUpdate(clientInfo->weatherNetVersion, clientInfo->clientState.netCompatibilityRules()); if (!skyDelta.empty() || !weatherDelta.empty()) clientInfo->outgoingPackets.append(make_shared(std::move(skyDelta), std::move(weatherDelta))); @@ -1866,12 +1868,14 @@ void WorldServer::queueUpdatePackets(ConnectionId clientId, bool sendRemoteUpdat EntityId entityId = monitoredEntity->entityId(); ConnectionId connectionId = connectionForEntity(entityId); if (connectionId != clientId) { + auto netRules = clientInfo->clientState.netCompatibilityRules(); if (auto version = clientInfo->clientSlavesNetVersion.ptr(entityId)) { if (auto updateSetPacket = updateSetPackets.value(connectionId)) { auto pair = make_pair(entityId, *version); - auto i = m_netStateCache.find(pair); - if (i == m_netStateCache.end()) - i = m_netStateCache.insert(pair, monitoredEntity->writeNetState(*version)).first; + auto& cache = netRules.isLegacy ? m_legacyNetStateCache : m_netStateCache; + auto i = cache.find(pair); + if (i == cache.end()) + i = cache.insert(pair, monitoredEntity->writeNetState(*version, netRules)).first; const auto& netState = i->second; if (!netState.first.empty()) updateSetPacket->deltas[entityId] = netState.first; @@ -1879,7 +1883,7 @@ void WorldServer::queueUpdatePackets(ConnectionId clientId, bool sendRemoteUpdat } } else if (!monitoredEntity->masterOnly()) { // Client was unaware of this entity until now - auto firstUpdate = monitoredEntity->writeNetState(); + auto firstUpdate = monitoredEntity->writeNetState(0, netRules); clientInfo->clientSlavesNetVersion.add(entityId, firstUpdate.second); clientInfo->outgoingPackets.append(make_shared(monitoredEntity->entityType(), entityFactory->netStoreEntity(monitoredEntity), std::move(firstUpdate.first), entityId)); @@ -2075,7 +2079,8 @@ void WorldServer::removeEntity(EntityId entityId, bool andDie) { for (auto const& pair : m_clientInfo) { auto& clientInfo = pair.second; if (auto version = clientInfo->clientSlavesNetVersion.maybeTake(entity->entityId())) { - ByteArray finalDelta = entity->writeNetState(*version).first; + auto netRules = clientInfo->clientState.netCompatibilityRules(); + ByteArray finalDelta = entity->writeNetState(*version, netRules).first; clientInfo->outgoingPackets.append(make_shared(entity->entityId(), std::move(finalDelta), andDie)); } } diff --git a/source/game/StarWorldServer.hpp b/source/game/StarWorldServer.hpp index 9e319e5..a87f72d 100644 --- a/source/game/StarWorldServer.hpp +++ b/source/game/StarWorldServer.hpp @@ -87,7 +87,7 @@ public: // Returns false if the client id already exists, or the spawn target is // invalid. - bool addClient(ConnectionId clientId, SpawnTarget const& spawnTarget, bool isLocal, bool isAdmin = false); + bool addClient(ConnectionId clientId, SpawnTarget const& spawnTarget, bool isLocal, bool isAdmin = false, NetCompatibilityRules netRules = {}); // Removes client, sends the WorldStopPacket, and returns any pending packets // for that client @@ -375,6 +375,7 @@ private: List m_workingCollisionBlocks; HashMap, pair> m_netStateCache; + HashMap, pair> m_legacyNetStateCache; OrderedHashMap> m_clientInfo; GameTimer m_entityUpdateTimer; diff --git a/source/game/StarWorldServerThread.cpp b/source/game/StarWorldServerThread.cpp index 1e1f51a..45959ea 100644 --- a/source/game/StarWorldServerThread.cpp +++ b/source/game/StarWorldServerThread.cpp @@ -66,10 +66,10 @@ bool WorldServerThread::spawnTargetValid(SpawnTarget const& spawnTarget) { } } -bool WorldServerThread::addClient(ConnectionId clientId, SpawnTarget const& spawnTarget, bool isLocal, bool isAdmin) { +bool WorldServerThread::addClient(ConnectionId clientId, SpawnTarget const& spawnTarget, bool isLocal, bool isAdmin, NetCompatibilityRules netRules) { try { RecursiveMutexLocker locker(m_mutex); - if (m_worldServer->addClient(clientId, spawnTarget, isLocal, isAdmin)) { + if (m_worldServer->addClient(clientId, spawnTarget, isLocal, isAdmin, netRules)) { m_clients.add(clientId); return true; } diff --git a/source/game/StarWorldServerThread.hpp b/source/game/StarWorldServerThread.hpp index ae1e666..3223912 100644 --- a/source/game/StarWorldServerThread.hpp +++ b/source/game/StarWorldServerThread.hpp @@ -38,7 +38,7 @@ public: bool spawnTargetValid(SpawnTarget const& spawnTarget); - bool addClient(ConnectionId clientId, SpawnTarget const& spawnTarget, bool isLocal, bool isAdmin = false); + bool addClient(ConnectionId clientId, SpawnTarget const& spawnTarget, bool isLocal, bool isAdmin = false, NetCompatibilityRules netRules = {}); // Returns final outgoing packets List removeClient(ConnectionId clientId); diff --git a/source/game/interfaces/StarActivatableItem.hpp b/source/game/interfaces/StarActivatableItem.hpp index c8802c0..6501d0b 100644 --- a/source/game/interfaces/StarActivatableItem.hpp +++ b/source/game/interfaces/StarActivatableItem.hpp @@ -1,5 +1,4 @@ -#ifndef STAR_ACTIVATABLE_ITEM_HPP -#define STAR_ACTIVATABLE_ITEM_HPP +#pragma once #include "StarConfig.hpp" @@ -16,6 +15,4 @@ public: virtual void activate() = 0; }; -} - -#endif +} \ No newline at end of file diff --git a/source/game/interfaces/StarEntity.cpp b/source/game/interfaces/StarEntity.cpp index cbc968f..150fcbd 100644 --- a/source/game/interfaces/StarEntity.cpp +++ b/source/game/interfaces/StarEntity.cpp @@ -1,5 +1,6 @@ #include "StarEntity.hpp" #include "StarDamageManager.hpp" +#include "StarNetCompatibility.hpp" namespace Star { @@ -43,11 +44,11 @@ void Entity::uninit() { m_entityId = NullEntityId; } -pair Entity::writeNetState(uint64_t) { +pair Entity::writeNetState(uint64_t fromVersion, NetCompatibilityRules rules) { return {ByteArray(), 0}; } -void Entity::readNetState(ByteArray, float) {} +void Entity::readNetState(ByteArray data, float interpolationTime, NetCompatibilityRules rules) {} void Entity::enableInterpolation(float) {} diff --git a/source/game/interfaces/StarEntity.hpp b/source/game/interfaces/StarEntity.hpp index 7da2a41..56bd5ac 100644 --- a/source/game/interfaces/StarEntity.hpp +++ b/source/game/interfaces/StarEntity.hpp @@ -3,6 +3,7 @@ #include "StarCasting.hpp" #include "StarDamage.hpp" #include "StarLightSource.hpp" +#include "StarDataStream.hpp" namespace Star { @@ -63,11 +64,11 @@ public: // uninitalized. Should return the delta to be written to the slave, along // with the version to pass into writeDeltaState on the next call. The first // delta written to a slave entity will always be the delta starting with 0. - virtual pair writeNetState(uint64_t fromVersion = 0); + virtual pair writeNetState(uint64_t fromVersion = 0, NetCompatibilityRules rules = {}); // Will be called with deltas written by writeDeltaState, including if the // delta is empty. interpolationTime will be provided if interpolation is // enabled. - virtual void readNetState(ByteArray data, float interpolationTime = 0.0); + virtual void readNetState(ByteArray data, float interpolationTime = 0.0f, NetCompatibilityRules rules = {}); virtual void enableInterpolation(float extrapolationHint); virtual void disableInterpolation(); diff --git a/source/game/scripting/StarRootLuaBindings.cpp b/source/game/scripting/StarRootLuaBindings.cpp index 50d18e8..0ce7866 100644 --- a/source/game/scripting/StarRootLuaBindings.cpp +++ b/source/game/scripting/StarRootLuaBindings.cpp @@ -237,14 +237,14 @@ LuaCallbacks LuaBindings::makeRootCallbacks() { callbacks.registerCallback("getConfigurationPath", [root](String const& path) -> Json { - if (path.beginsWith("title")) + if (path.empty() || path.beginsWith("title")) throw ConfigurationException(strf("cannot get {}", path)); else return root->configuration()->getPath(path); }); callbacks.registerCallback("setConfigurationPath", [root](String const& path, Json const& value) { - if (path.beginsWith("safeScripts")) + if (path.empty() || path.beginsWith("safeScripts")) throw ConfigurationException(strf("cannot set {}", path)); else root->configuration()->setPath(path, value); From c68ebd2e0e13facd09fc9d194111462266a86068 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Wed, 11 Sep 2024 15:20:48 +1000 Subject: [PATCH 003/181] Tooltip improvements --- source/windowing/StarPaneManager.cpp | 53 +++++++++++++++++----------- source/windowing/StarPaneManager.hpp | 2 +- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/source/windowing/StarPaneManager.cpp b/source/windowing/StarPaneManager.cpp index 4f4cee7..0bdc159 100644 --- a/source/windowing/StarPaneManager.cpp +++ b/source/windowing/StarPaneManager.cpp @@ -184,7 +184,7 @@ bool PaneManager::sendInputEvent(InputEvent const& event) { } } - if (event.is() || vmag(m_tooltipInitialPosition - m_tooltipLastMousePos) > m_tooltipMouseoverRadius) { + if (event.is()) { m_tooltipShowTimer = m_tooltipMouseoverTime; if (m_activeTooltip) { dismiss(m_activeTooltip); @@ -271,36 +271,47 @@ void PaneManager::render() { void PaneManager::update(float dt) { m_tooltipShowTimer -= GlobalTimestep; - if (m_tooltipShowTimer < 0 && !m_activeTooltip) { + if (m_tooltipParentPane.expired()) + m_tooltipParentPane.reset(); + + bool removeTooltip = vmag(m_tooltipInitialPosition - m_tooltipLastMousePos) > m_tooltipMouseoverRadius + || m_tooltipParentPane.expired() || m_tooltipParentPane.lock()->inWindow(m_tooltipLastMousePos); + + if (removeTooltip) { + dismiss(m_activeTooltip); + m_activeTooltip.reset(); + m_tooltipParentPane.reset(); + } + + // Scan for a new tooltip if we just removed the old one, or the show timer has expired + if (removeTooltip || (m_tooltipShowTimer < 0 && !m_activeTooltip)) { if (auto parentPane = getPaneAt(m_tooltipLastMousePos)) { if (auto tooltip = parentPane->createTooltip(m_tooltipLastMousePos)) { m_activeTooltip = std::move(tooltip); m_tooltipParentPane = std::move(parentPane); m_tooltipInitialPosition = m_tooltipLastMousePos; displayPane(PaneLayer::Tooltip, m_activeTooltip); - - Vec2I offsetDirection = Vec2I::filled(1); - Vec2I offsetAdjust = Vec2I(); - - if (m_tooltipLastMousePos[0] + m_tooltipMouseOffset[0] + m_activeTooltip->size()[0] > (int)m_context->windowWidth() / m_context->interfaceScale()) { - offsetDirection[0] = -1; - offsetAdjust[0] = -m_activeTooltip->size()[0]; - } - - if (m_tooltipLastMousePos[1] + m_tooltipMouseOffset[1] - m_activeTooltip->size()[1] < 0) - offsetDirection[1] = -1; - else - offsetAdjust[1] = -m_activeTooltip->size()[1]; - - m_activeTooltip->setPosition(m_tooltipLastMousePos + (offsetAdjust + m_tooltipMouseOffset.piecewiseMultiply(offsetDirection))); } else { m_tooltipShowTimer = m_tooltipMouseoverTime; } } - } else if (m_activeTooltip && !m_tooltipParentPane->isDisplayed()) { - dismiss(m_activeTooltip); - m_activeTooltip.reset(); - m_tooltipParentPane.reset(); + } + + if (m_activeTooltip) { + Vec2I offsetDirection = Vec2I::filled(1); + Vec2I offsetAdjust = Vec2I(); + + if (m_tooltipLastMousePos[0] + m_tooltipMouseOffset[0] + m_activeTooltip->size()[0] > (int)m_context->windowWidth() / m_context->interfaceScale()) { + offsetDirection[0] = -1; + offsetAdjust[0] = -m_activeTooltip->size()[0]; + } + + if (m_tooltipLastMousePos[1] + m_tooltipMouseOffset[1] - m_activeTooltip->size()[1] < 0) + offsetDirection[1] = -1; + else + offsetAdjust[1] = -m_activeTooltip->size()[1]; + + m_activeTooltip->setPosition(m_tooltipLastMousePos + (offsetAdjust + m_tooltipMouseOffset.piecewiseMultiply(offsetDirection))); } for (auto const& layerPair : m_displayedPanes) { diff --git a/source/windowing/StarPaneManager.hpp b/source/windowing/StarPaneManager.hpp index ffa46c7..b6d1032 100644 --- a/source/windowing/StarPaneManager.hpp +++ b/source/windowing/StarPaneManager.hpp @@ -100,7 +100,7 @@ private: Vec2I m_tooltipLastMousePos; Vec2I m_tooltipInitialPosition; PanePtr m_activeTooltip; - PanePtr m_tooltipParentPane; + PaneWeakPtr m_tooltipParentPane; }; } From a6b20df3f0ddac5c235d10373d7d5f0876af99f9 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Wed, 11 Sep 2024 15:23:35 +1000 Subject: [PATCH 004/181] fix button click not playing when returning from a GUI and then clicking it again --- source/windowing/StarButtonWidget.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/windowing/StarButtonWidget.cpp b/source/windowing/StarButtonWidget.cpp index 258ac55..0412ae5 100644 --- a/source/windowing/StarButtonWidget.cpp +++ b/source/windowing/StarButtonWidget.cpp @@ -165,6 +165,12 @@ void ButtonWidget::mouseOut() { void ButtonWidget::mouseReturnStillDown() { Widget::mouseReturnStillDown(); + if (!isPressed()) { + auto assets = Root::singleton().assets(); + auto sound = Random::randValueFrom(m_clickSounds, ""); + if (!sound.empty()) + context()->playAudio(sound); + } m_hovered = true; m_pressed = true; } From 4c78b7365a07ce9bf8fe3fc3434584c87aff32f4 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Wed, 11 Sep 2024 15:24:01 +1000 Subject: [PATCH 005/181] Experimental BTree changes --- source/core/StarBTreeDatabase.cpp | 220 ++++++++++++++++++++++-------- source/core/StarBTreeDatabase.hpp | 13 +- 2 files changed, 173 insertions(+), 60 deletions(-) diff --git a/source/core/StarBTreeDatabase.cpp b/source/core/StarBTreeDatabase.cpp index 19b0bd2..f66bea1 100644 --- a/source/core/StarBTreeDatabase.cpp +++ b/source/core/StarBTreeDatabase.cpp @@ -1,6 +1,7 @@ #include "StarBTreeDatabase.hpp" #include "StarSha256.hpp" #include "StarVlqEncoding.hpp" +#include "StarLogging.hpp" namespace Star { @@ -243,7 +244,7 @@ uint32_t BTreeDatabase::freeBlockCount() { indexBlockIndex = indexBlock.nextFreeBlock; } - count += m_availableBlocks.size() + m_pendingFree.size(); + count += m_availableBlocks.size(); // Include untracked blocks at the end of the file in the free count. count += (m_device->size() - m_deviceSize) / m_blockSize; @@ -272,7 +273,7 @@ uint32_t BTreeDatabase::leafBlockCount() { return true; } - BTreeDatabase* parent; + BTreeDatabase* parent = nullptr; BlockIndex leafBlockCount = 0; }; @@ -293,8 +294,8 @@ void BTreeDatabase::rollback() { m_availableBlocks.clear(); m_indexCache.clear(); + m_uncommittedWrites.clear(); m_uncommitted.clear(); - m_pendingFree.clear(); readRoot(); @@ -305,7 +306,8 @@ void BTreeDatabase::rollback() { void BTreeDatabase::close(bool closeDevice) { WriteLocker writeLocker(m_lock); if (m_open) { - doCommit(); + if (!tryFlatten()) + doCommit(); m_indexCache.clear(); @@ -536,7 +538,7 @@ auto BTreeDatabase::BTreeImpl::loadIndex(Pointer pointer) -> Index { index->pointers.resize(s); for (uint32_t i = 0; i < s; ++i) { auto& e = index->pointers[i]; - e.key =buffer.readBytes(parent->m_keySize); + e.key = buffer.readBytes(parent->m_keySize); e.pointer = buffer.read(); } @@ -896,17 +898,25 @@ void BTreeDatabase::rawReadBlock(BlockIndex blockIndex, size_t blockOffset, char if (size <= 0) return; - m_device->readFullAbsolute(HeaderSize + blockIndex * (StreamOffset)m_blockSize + blockOffset, block, size); + if (auto buffer = m_uncommittedWrites.ptr(blockIndex)) + buffer->copyTo(block, blockOffset, size); + else + m_device->readFullAbsolute(HeaderSize + blockIndex * (StreamOffset)m_blockSize + blockOffset, block, size); } -void BTreeDatabase::rawWriteBlock(BlockIndex blockIndex, size_t blockOffset, char const* block, size_t size) const { +void BTreeDatabase::rawWriteBlock(BlockIndex blockIndex, size_t blockOffset, char const* block, size_t size) { if (blockOffset > m_blockSize || size > m_blockSize - blockOffset) throw DBException::format("Write past end of block, offset: {} size {}", blockOffset, size); if (size <= 0) return; - m_device->writeFullAbsolute(HeaderSize + blockIndex * (StreamOffset)m_blockSize + blockOffset, block, size); + StreamOffset blockStart = HeaderSize + blockIndex * (StreamOffset)m_blockSize; + auto buffer = m_uncommittedWrites.find(blockIndex); + if (buffer == m_uncommittedWrites.end()) + buffer = m_uncommittedWrites.emplace(blockIndex, m_device->readBytesAbsolute(blockStart, m_blockSize)).first; + + buffer->second.writeFrom(block, blockOffset, size); } auto BTreeDatabase::readFreeIndexBlock(BlockIndex blockIndex) -> FreeIndexBlock { @@ -991,12 +1001,12 @@ auto BTreeDatabase::leafTailBlocks(BlockIndex leafPointer) -> List { } void BTreeDatabase::freeBlock(BlockIndex b) { - if (m_uncommitted.contains(b)) { + if (m_uncommitted.contains(b)) m_uncommitted.remove(b); - m_availableBlocks.add(b); - } else { - m_pendingFree.append(b); - } + if (m_uncommittedWrites.contains(b)) + m_uncommittedWrites.remove(b); + + m_availableBlocks.add(b); } auto BTreeDatabase::reserveBlock() -> BlockIndex { @@ -1007,10 +1017,7 @@ auto BTreeDatabase::reserveBlock() -> BlockIndex { FreeIndexBlock indexBlock = readFreeIndexBlock(m_headFreeIndexBlock); for (auto const& b : indexBlock.freeBlocks) m_availableBlocks.add(b); - // We cannot make available the block itself, because we must maintain - // atomic consistency. We will need to free this block later and commit - // the new free index block chain. - m_pendingFree.append(m_headFreeIndexBlock); + m_availableBlocks.add(m_headFreeIndexBlock); m_headFreeIndexBlock = indexBlock.nextFreeBlock; } @@ -1068,65 +1075,168 @@ void BTreeDatabase::readRoot() { } void BTreeDatabase::doCommit() { - if (m_availableBlocks.empty() && m_pendingFree.empty() && m_uncommitted.empty()) + if (m_availableBlocks.empty() && m_uncommitted.empty()) return; - if (!m_availableBlocks.empty() || !m_pendingFree.empty()) { + if (!m_availableBlocks.empty()) { // First, read the existing head FreeIndexBlock, if it exists FreeIndexBlock indexBlock = FreeIndexBlock{InvalidBlockIndex, {}}; - if (m_headFreeIndexBlock != InvalidBlockIndex) { + + auto newBlock = [&]() -> BlockIndex { + if (!m_availableBlocks.empty()) + return m_availableBlocks.takeFirst(); + else + return makeEndBlock(); + }; + + if (m_headFreeIndexBlock != InvalidBlockIndex) indexBlock = readFreeIndexBlock(m_headFreeIndexBlock); - if (indexBlock.freeBlocks.size() >= maxFreeIndexLength()) { - // If the existing head free index block is full, then we should start a - // new one and leave it alone - indexBlock.nextFreeBlock = m_headFreeIndexBlock; - indexBlock.freeBlocks.clear(); - } else { - // If we are copying an existing free index block, the old free index - // block will be a newly freed block - indexBlock.freeBlocks.append(m_headFreeIndexBlock); - } - } + else + m_headFreeIndexBlock = newBlock(); - // Then, we need to write all the available blocks, which are safe to write - // to, and the pending free blocks, which are NOT safe to write to, to the - // FreeIndexBlock chain. + // Then, we need to write all the available blocks to the FreeIndexBlock chain. while (true) { - if (indexBlock.freeBlocks.size() < maxFreeIndexLength() && (!m_availableBlocks.empty() || !m_pendingFree.empty())) { - // If we have room on our current FreeIndexblock, just add a block to - // it. Prioritize the pending free blocks, because we cannot use those - // to write to. - BlockIndex toAdd; - if (m_pendingFree.empty()) - toAdd = m_availableBlocks.takeFirst(); - else - toAdd = m_pendingFree.takeFirst(); - + // If we have room on our current FreeIndexBlock, just add a block to it. + if (!m_availableBlocks.empty() && indexBlock.freeBlocks.size() < maxFreeIndexLength()) { + BlockIndex toAdd = m_availableBlocks.takeFirst(); indexBlock.freeBlocks.append(toAdd); } else { - // If our index block is full OR we are out of blocks to free, then - // need to write a new head free index block. - if (m_availableBlocks.empty()) - m_headFreeIndexBlock = makeEndBlock(); - else - m_headFreeIndexBlock = m_availableBlocks.takeFirst(); + // Update the current head free index block. writeFreeIndexBlock(m_headFreeIndexBlock, indexBlock); // If we're out of blocks to free, then we're done - if (m_availableBlocks.empty() && m_pendingFree.empty()) + if (m_availableBlocks.empty()) break; - indexBlock.nextFreeBlock = m_headFreeIndexBlock; - indexBlock.freeBlocks.clear(); + // If our head free index block is full, then + // need to write a new head free index block. + if (indexBlock.freeBlocks.size() >= maxFreeIndexLength()) { + indexBlock.nextFreeBlock = m_headFreeIndexBlock; + indexBlock.freeBlocks.clear(); + + m_headFreeIndexBlock = newBlock(); + writeFreeIndexBlock(m_headFreeIndexBlock, indexBlock); + } } } } + + commitWrites(); writeRoot(); - m_uncommitted.clear(); } +void BTreeDatabase::commitWrites() { + for (auto& write : m_uncommittedWrites) + m_device->writeFullAbsolute(HeaderSize + write.first * (StreamOffset)m_blockSize, write.second.ptr(), m_blockSize); + + m_device->sync(); + m_uncommittedWrites.clear(); +} + +bool BTreeDatabase::tryFlatten() { + if (m_headFreeIndexBlock == InvalidBlockIndex || m_rootIsLeaf || !m_device->isWritable()) + return false; + + BlockIndex freeBlockCount = 0; + BlockIndex indexBlockIndex = m_headFreeIndexBlock; + while (indexBlockIndex != InvalidBlockIndex) { + FreeIndexBlock indexBlock = readFreeIndexBlock(indexBlockIndex); + freeBlockCount += 1 + indexBlock.freeBlocks.size(); + indexBlockIndex = indexBlock.nextFreeBlock; + } + + BlockIndex expectedBlockCount = (m_deviceSize - HeaderSize) / m_blockSize; + float free = float(freeBlockCount) / float(expectedBlockCount); + if (free < 0.05f) + return false; + + Logger::info("[BTreeDatabase] File '{}' is {:.2f}% free space, flattening", m_device->deviceName(), free * 100.f); + + indexBlockIndex = m_headFreeIndexBlock; + { + List availableBlocksList; + do { + FreeIndexBlock indexBlock = readFreeIndexBlock(indexBlockIndex); + availableBlocksList.appendAll(indexBlock.freeBlocks); + availableBlocksList.append(indexBlockIndex); + indexBlockIndex = indexBlock.nextFreeBlock; + } while (indexBlockIndex != InvalidBlockIndex); + m_headFreeIndexBlock = InvalidBlockIndex; + + sort(availableBlocksList); + for (auto& availableBlock : availableBlocksList) + m_availableBlocks.insert(m_availableBlocks.end(), availableBlock); + } + + BlockIndex count = 1; // 1 to include root index + + double start = Time::monotonicTime(); + auto index = m_impl.loadIndex(m_impl.rootPointer()); + if (flattenVisitor(index, count)) { + m_impl.deleteIndex(index); + index->self = InvalidBlockIndex; + m_root = m_impl.storeIndex(index); + } + + m_availableBlocks.clear(); + m_device->resize(m_deviceSize = HeaderSize + (StreamOffset)m_blockSize * count); + + m_indexCache.clear(); + commitWrites(); + writeRoot(); + m_uncommitted.clear(); + + Logger::info("[BTreeDatabase] Finished flattening '{}' in {:.2f} milliseconds", m_device->deviceName(), (Time::monotonicTime() - start) * 1000.f); + return true; +} + +bool BTreeDatabase::flattenVisitor(BTreeImpl::Index& index, BlockIndex& count) { + auto pointerCount = index->pointerCount(); + count += pointerCount; + bool canStore = !m_availableBlocks.empty(); + + bool needsStore = false; + if (m_impl.indexLevel(index) == 0) { + for (size_t i = 0; i != pointerCount; ++i) { + auto indexPointer = index->pointer(i); + auto tailBlocks = leafTailBlocks(indexPointer); + if (canStore) { + bool leafNeedsStore = m_availableBlocks.first() < indexPointer; + + if (!leafNeedsStore) + for (size_t i = 0; !leafNeedsStore && i != tailBlocks.size(); ++i) + if (m_availableBlocks.first() < tailBlocks[i]) + leafNeedsStore = true; + + if (leafNeedsStore) { + auto leaf = m_impl.loadLeaf(indexPointer); + m_impl.deleteLeaf(leaf); + leaf->self = InvalidBlockIndex; + index->updatePointer(i, m_impl.storeLeaf(leaf)); + tailBlocks = leafTailBlocks(leaf->self); + needsStore = true; + } + canStore = !m_availableBlocks.empty(); + } + count += tailBlocks.size(); + } + } else { + for (size_t i = 0; i != pointerCount; ++i) { + auto childIndex = m_impl.loadIndex(index->pointer(i)); + if (canStore && flattenVisitor(childIndex, count)) { + m_impl.deleteIndex(childIndex); + childIndex->self = InvalidBlockIndex; + index->updatePointer(i, m_impl.storeIndex(childIndex)); + canStore = !m_availableBlocks.empty(); + needsStore = true; + } + } + } + return needsStore || (canStore && m_availableBlocks.first() < index->self); +} + void BTreeDatabase::checkIfOpen(char const* methodName, bool shouldBeOpen) const { if (shouldBeOpen && !m_open) throw DBException::format("BTreeDatabase method '{}' called when not open, must be open.", methodName); @@ -1146,7 +1256,7 @@ void BTreeDatabase::checkKeySize(ByteArray const& k) const { } uint32_t BTreeDatabase::maxFreeIndexLength() const { - return (m_blockSize - 2 - sizeof(BlockIndex) - 4) / sizeof(BlockIndex); + return (m_blockSize / sizeof(BlockIndex)) - 2 - sizeof(BlockIndex) - 4; } BTreeSha256Database::BTreeSha256Database() { diff --git a/source/core/StarBTreeDatabase.hpp b/source/core/StarBTreeDatabase.hpp index f1b88a1..b3a530f 100644 --- a/source/core/StarBTreeDatabase.hpp +++ b/source/core/StarBTreeDatabase.hpp @@ -230,7 +230,7 @@ private: void updateBlock(BlockIndex blockIndex, ByteArray const& block); void rawReadBlock(BlockIndex blockIndex, size_t blockOffset, char* block, size_t size) const; - void rawWriteBlock(BlockIndex blockIndex, size_t blockOffset, char const* block, size_t size) const; + void rawWriteBlock(BlockIndex blockIndex, size_t blockOffset, char const* block, size_t size); void updateHeadFreeIndexBlock(BlockIndex newHead); @@ -251,6 +251,9 @@ private: void writeRoot(); void readRoot(); void doCommit(); + void commitWrites(); + bool tryFlatten(); + bool flattenVisitor(BTreeImpl::Index& index, BlockIndex& count); void checkIfOpen(char const* methodName, bool shouldBeOpen) const; void checkBlockIndex(size_t blockIndex) const; @@ -285,14 +288,14 @@ private: bool m_dirty; // Blocks that can be freely allocated and written to without violating - // atomic consistency + // atomic consistency. Set m_availableBlocks; - // Blocks to be freed on next commit. - Deque m_pendingFree; - // Blocks that have been written in uncommitted portions of the tree. Set m_uncommitted; + + // Temporarily holds written data so that it can be rolled back. + mutable Map m_uncommittedWrites; }; // Version of BTreeDatabase that hashes keys with SHA-256 to produce a unique From 5a75473e16afb8152aab943fd316d9820835f465 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Wed, 11 Sep 2024 18:18:20 +1000 Subject: [PATCH 006/181] try to fix that freaking rare font bug again --- source/core/StarFont.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/source/core/StarFont.cpp b/source/core/StarFont.cpp index 47569f2..07a6265 100644 --- a/source/core/StarFont.cpp +++ b/source/core/StarFont.cpp @@ -30,8 +30,8 @@ FTContext ftContext; struct FontImpl { FT_Face face; - unsigned loadedPixelSize = 0; String::Char loadedChar = 0; + unsigned renderedPixelSize = 0; }; FontPtr Font::loadFont(String const& fileName, unsigned pixelSize) { @@ -84,7 +84,8 @@ unsigned Font::width(String::Char c) { if (auto width = m_widthCache.maybe({c, m_pixelSize})) { return *width; } else { - FT_Load_Char(m_fontImpl->face, c, FontLoadFlags); + if (m_fontImpl->loadedChar != c) + FT_Load_Char(m_fontImpl->face, m_fontImpl->loadedChar = c, FontLoadFlags); unsigned newWidth = (m_fontImpl->face->glyph->linearHoriAdvance + 32768) / 65536; m_widthCache.insert({c, m_pixelSize}, newWidth); return newWidth; @@ -98,19 +99,19 @@ tuple Font::render(String::Char c) { FT_Face face = m_fontImpl->face; - if (m_fontImpl->loadedPixelSize != m_pixelSize || m_fontImpl->loadedChar != c) { - FT_UInt glyph_index = FT_Get_Char_Index(face, c); - if (FT_Load_Glyph(face, glyph_index, FontLoadFlags) != 0) + if (m_fontImpl->loadedChar != c) { + if (FT_Load_Glyph(face, FT_Get_Char_Index(face, m_fontImpl->loadedChar = c), FontLoadFlags) != 0) return {}; - // convert to an anti-aliased bitmap + m_fontImpl->renderedPixelSize = 0; + } + + if (m_fontImpl->renderedPixelSize != m_pixelSize) { + m_fontImpl->renderedPixelSize = m_pixelSize; if (FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL) != 0) return {}; } - m_fontImpl->loadedPixelSize = m_pixelSize; - m_fontImpl->loadedChar = c; - FT_GlyphSlot slot = face->glyph; if (!slot->bitmap.buffer) return {}; From 7408981e131f7cdd897a3c5924ea14b272986e88 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Wed, 11 Sep 2024 18:22:44 +1000 Subject: [PATCH 007/181] use a version number rather than a bool more flexible, allows for backwards compat with older OpenSB versions & not just vanilla Starbound --- source/base/CMakeLists.txt | 4 +- source/core/CMakeLists.txt | 5 ++- source/core/StarDataStream.cpp | 5 +-- source/core/StarNetCompatibility.cpp | 7 +++ source/core/StarNetCompatibility.hpp | 54 +++++++++++++++--------- source/core/StarNetElement.hpp | 18 ++++---- source/{base => core}/StarVersion.cpp.in | 0 source/{base => core}/StarVersion.hpp | 0 source/game/StarNetPackets.cpp | 1 - source/game/StarNetPackets.hpp | 1 - source/game/StarStatusController.cpp | 8 ++-- source/game/StarUniverseClient.cpp | 25 +++++++---- source/game/StarUniverseServer.cpp | 7 ++- source/game/StarWorldClient.cpp | 2 +- source/game/StarWorldServer.cpp | 3 +- source/game/StarWorldServer.hpp | 3 +- 16 files changed, 85 insertions(+), 58 deletions(-) create mode 100644 source/core/StarNetCompatibility.cpp rename source/{base => core}/StarVersion.cpp.in (100%) rename source/{base => core}/StarVersion.hpp (100%) diff --git a/source/base/CMakeLists.txt b/source/base/CMakeLists.txt index e813e45..e77d9ff 100644 --- a/source/base/CMakeLists.txt +++ b/source/base/CMakeLists.txt @@ -18,7 +18,6 @@ SET (star_base_HEADERS StarMixer.hpp StarPackedAssetSource.hpp StarRootBase.hpp - StarVersion.hpp StarVersionOptionParser.hpp StarWorldGeometry.hpp scripting/StarImageLuaBindings.hpp @@ -40,8 +39,7 @@ SET (star_base_SOURCES scripting/StarImageLuaBindings.cpp ) -CONFIGURE_FILE (StarVersion.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/StarVersion.cpp) -ADD_LIBRARY (star_base OBJECT ${star_base_SOURCES} ${star_base_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/StarVersion.cpp) +ADD_LIBRARY (star_base OBJECT ${star_base_SOURCES} ${star_base_HEADERS}) IF(STAR_PRECOMPILED_HEADERS) TARGET_PRECOMPILE_HEADERS (star_base REUSE_FROM star_core) diff --git a/source/core/CMakeLists.txt b/source/core/CMakeLists.txt index bb8bd22..2f0c858 100644 --- a/source/core/CMakeLists.txt +++ b/source/core/CMakeLists.txt @@ -124,6 +124,7 @@ SET (star_core_HEADERS StarUnicode.hpp StarUuid.hpp StarVector.hpp + StarVersion.hpp StarVlqEncoding.hpp StarWeightedPool.hpp StarWorkerPool.hpp @@ -164,6 +165,7 @@ SET (star_core_SOURCES StarLua.cpp StarLuaConverters.cpp StarMemory.cpp + StarNetCompatibility.cpp StarNetElement.cpp StarNetElementBasicFields.cpp StarNetElementGroup.cpp @@ -219,7 +221,8 @@ ELSEIF (STAR_SYSTEM_FAMILY_WINDOWS) ENDIF () -ADD_LIBRARY (star_core OBJECT ${star_core_SOURCES} ${star_core_HEADERS}) +CONFIGURE_FILE (StarVersion.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/StarVersion.cpp) +ADD_LIBRARY (star_core OBJECT ${star_core_SOURCES} ${star_core_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/StarVersion.cpp) IF(STAR_PRECOMPILED_HEADERS) TARGET_PRECOMPILE_HEADERS (star_core PUBLIC StarPch.hpp) diff --git a/source/core/StarDataStream.cpp b/source/core/StarDataStream.cpp index 1224f54..3a4ed0c 100644 --- a/source/core/StarDataStream.cpp +++ b/source/core/StarDataStream.cpp @@ -36,10 +36,7 @@ void DataStream::setStreamCompatibilityVersion(unsigned streamCompatibilityVersi } void DataStream::setStreamCompatibilityVersion(NetCompatibilityRules const& rules) { - if (rules.isLegacy) - m_streamCompatibilityVersion = 1; - else - m_streamCompatibilityVersion = CurrentStreamVersion; + m_streamCompatibilityVersion = rules.version(); } ByteArray DataStream::readBytes(size_t len) { diff --git a/source/core/StarNetCompatibility.cpp b/source/core/StarNetCompatibility.cpp new file mode 100644 index 0000000..fdd53fb --- /dev/null +++ b/source/core/StarNetCompatibility.cpp @@ -0,0 +1,7 @@ +#include "StarNetCompatibility.hpp" + +namespace Star { + +VersionNumber const OpenProtocolVersion = 2; + +} \ No newline at end of file diff --git a/source/core/StarNetCompatibility.hpp b/source/core/StarNetCompatibility.hpp index 730546e..4b950ab 100644 --- a/source/core/StarNetCompatibility.hpp +++ b/source/core/StarNetCompatibility.hpp @@ -1,40 +1,54 @@ #pragma once -#include "StarDataStream.hpp" +#include "StarVersion.hpp" +#include "StarHash.hpp" namespace Star { +extern VersionNumber const OpenProtocolVersion; -enum class NetCompatibilityFilter { - None = 0, - Old = 1, - New = 2 -}; +constexpr VersionNumber AnyVersion = 0xFFFFFFFF; +constexpr VersionNumber LegacyVersion = 0; -struct NetCompatibilityRules { - NetCompatibilityRules() = default; +class NetCompatibilityRules { +public: + NetCompatibilityRules(); NetCompatibilityRules(uint64_t) = delete; - NetCompatibilityRules(bool legacy); + NetCompatibilityRules(VersionNumber version); - bool checkFilter(NetCompatibilityFilter const& filter) const; + VersionNumber version() const; + void setVersion(VersionNumber version); + bool isLegacy() const; - bool isLegacy = false; + bool operator==(NetCompatibilityRules const& a) const; + +private: + VersionNumber m_version = OpenProtocolVersion; }; -inline NetCompatibilityRules::NetCompatibilityRules(bool legacy) : isLegacy(legacy) {} +inline NetCompatibilityRules::NetCompatibilityRules() : m_version(OpenProtocolVersion) {} -inline bool NetCompatibilityRules::checkFilter(NetCompatibilityFilter const& filter) const { - if (filter == NetCompatibilityFilter::None) - return true; - else if (isLegacy) - return filter == NetCompatibilityFilter::Old; - else - return filter == NetCompatibilityFilter::New; +inline NetCompatibilityRules::NetCompatibilityRules(VersionNumber v) : m_version(v) {} + +inline VersionNumber NetCompatibilityRules::version() const { + return m_version; +} + +inline void NetCompatibilityRules::setVersion(VersionNumber version) { + m_version = version; +} + +inline bool NetCompatibilityRules::isLegacy() const { + return m_version == LegacyVersion; +} + +inline bool NetCompatibilityRules::operator==(NetCompatibilityRules const& a) const { + return m_version == a.m_version; } template <> struct hash { size_t operator()(NetCompatibilityRules const& s) const { - return s.isLegacy; + return s.version(); } }; diff --git a/source/core/StarNetElement.hpp b/source/core/StarNetElement.hpp index 393dd3d..7d73b85 100644 --- a/source/core/StarNetElement.hpp +++ b/source/core/StarNetElement.hpp @@ -55,23 +55,25 @@ public: // received even if no deltas are produced, so no extrapolation takes place. virtual void blankNetDelta(float interpolationTime); - NetCompatibilityFilter netCompatibilityFilter() const; - void setNetCompatibilityFilter(NetCompatibilityFilter netFilter); + VersionNumber compatibilityVersion() const; + void setCompatibilityVersion(VersionNumber version); bool checkWithRules(NetCompatibilityRules const& rules) const; private: - NetCompatibilityFilter m_netCompatibilityFilter = NetCompatibilityFilter::None; + VersionNumber m_netCompatibilityVersion = AnyVersion; }; -inline NetCompatibilityFilter NetElement::netCompatibilityFilter() const { - return m_netCompatibilityFilter; +inline VersionNumber NetElement::compatibilityVersion() const { + return m_netCompatibilityVersion; } -inline void NetElement::setNetCompatibilityFilter(NetCompatibilityFilter netFilter) { - m_netCompatibilityFilter = netFilter; +inline void NetElement::setCompatibilityVersion(VersionNumber version) { + m_netCompatibilityVersion = version; } inline bool NetElement::checkWithRules(NetCompatibilityRules const& rules) const { - return rules.checkFilter(m_netCompatibilityFilter); + if (m_netCompatibilityVersion != AnyVersion) + return rules.version() >= m_netCompatibilityVersion; + return true; } } diff --git a/source/base/StarVersion.cpp.in b/source/core/StarVersion.cpp.in similarity index 100% rename from source/base/StarVersion.cpp.in rename to source/core/StarVersion.cpp.in diff --git a/source/base/StarVersion.hpp b/source/core/StarVersion.hpp similarity index 100% rename from source/base/StarVersion.hpp rename to source/core/StarVersion.hpp diff --git a/source/game/StarNetPackets.cpp b/source/game/StarNetPackets.cpp index dd80d76..b8605ed 100644 --- a/source/game/StarNetPackets.cpp +++ b/source/game/StarNetPackets.cpp @@ -5,7 +5,6 @@ namespace Star { VersionNumber const StarProtocolVersion = 747; -VersionNumber const OpenProtocolVersion = 1; EnumMap const PacketTypeNames{ {PacketType::ProtocolRequest, "ProtocolRequest"}, diff --git a/source/game/StarNetPackets.hpp b/source/game/StarNetPackets.hpp index e68a045..87a01cf 100644 --- a/source/game/StarNetPackets.hpp +++ b/source/game/StarNetPackets.hpp @@ -23,7 +23,6 @@ STAR_STRUCT(Packet); STAR_EXCEPTION(StarPacketException, IOException); extern VersionNumber const StarProtocolVersion; -extern VersionNumber const OpenProtocolVersion; // Packet types sent between the client and server over a NetSocket. Does not // correspond to actual packets, simply logical portions of NetSocket data. diff --git a/source/game/StarStatusController.cpp b/source/game/StarStatusController.cpp index a2a5e9c..325fc17 100644 --- a/source/game/StarStatusController.cpp +++ b/source/game/StarStatusController.cpp @@ -21,15 +21,15 @@ StatusController::StatusController(Json const& config) : m_statCollection(config m_statusProperties.reset(config.getObject("statusProperties", {})); m_statusProperties.setOverrides( [&](DataStream& ds, NetCompatibilityRules rules) { - if (rules.isLegacy) ds << m_statusProperties.baseMap(); + if (rules.version() <= 1) ds << m_statusProperties.baseMap(); else m_statusProperties.NetElementHashMap::netStore(ds, rules); }, [&](DataStream& ds, NetCompatibilityRules rules) { - if (rules.isLegacy) m_statusProperties.reset(ds.read()); + if (rules.version() <= 1) m_statusProperties.reset(ds.read()); else m_statusProperties.NetElementHashMap::netLoad(ds, rules); }, [&](DataStream& ds, uint64_t fromVersion, NetCompatibilityRules rules) { - if (rules.isLegacy) { + if (rules.version() <= 1) { if (m_statusProperties.shouldWriteNetDelta(fromVersion, rules)) { ds << m_statusProperties.baseMap(); return true; @@ -39,7 +39,7 @@ StatusController::StatusController(Json const& config) : m_statCollection(config return m_statusProperties.NetElementHashMap::writeNetDelta(ds, fromVersion, rules); }, [&](DataStream& ds, float interp, NetCompatibilityRules rules) { - if (rules.isLegacy) m_statusProperties.reset(ds.read()); + if (rules.version() <= 1) m_statusProperties.reset(ds.read()); else m_statusProperties.NetElementHashMap::readNetDelta(ds, interp, rules); } ); diff --git a/source/game/StarUniverseClient.cpp b/source/game/StarUniverseClient.cpp index 023140c..6038901 100644 --- a/source/game/StarUniverseClient.cpp +++ b/source/game/StarUniverseClient.cpp @@ -94,20 +94,27 @@ Maybe UniverseClient::connect(UniverseConnection connection, bool allowA else if (!protocolResponsePacket->allowed) return String(strf("Join failed! Server does not support connections with protocol version {}", StarProtocolVersion)); + NetCompatibilityRules compatibilityRules; + compatibilityRules.setVersion(LegacyVersion); bool legacyServer = protocolResponsePacket->compressionMode() != PacketCompressionMode::Enabled; if (!legacyServer) { - if (auto compressedSocket = as(&connection.packetSocket())) { - if (protocolResponsePacket->info) { - auto compressionName = protocolResponsePacket->info.getString("compression", "None"); + auto compressedSocket = as(&connection.packetSocket()); + if (protocolResponsePacket->info) { + compatibilityRules.setVersion(protocolResponsePacket->info.getUInt("openProtocolVersion", 1)); + auto compressionName = protocolResponsePacket->info.getString("compression", "None"); + if (compressedSocket) { auto compressionMode = NetCompressionModeNames.maybeLeft(compressionName); if (!compressionMode) return String(strf("Join failed! Unknown net stream connection type '{}'", compressionName)); Logger::info("UniverseClient: Using '{}' network stream compression", NetCompressionModeNames.getRight(*compressionMode)); compressedSocket->setCompressionStreamEnabled(compressionMode == NetCompressionMode::Zstd); - } else { + } + } else { + compatibilityRules.setVersion(1); // A version of 1 is OpenStarbound prior to the NetElement compatibility stuff + if (compressedSocket) { Logger::info("UniverseClient: Defaulting to Zstd network stream compression (older server version)"); - compressedSocket->setCompressionStreamEnabled(true);// old OpenSB server version always expects it! + compressedSocket->setCompressionStreamEnabled(true); } } } @@ -115,7 +122,10 @@ Maybe UniverseClient::connect(UniverseConnection connection, bool allowA 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); - clientConnect->info = JsonObject{ {"brand", "OpenStarbound"} }; + clientConnect->info = JsonObject{ + {"brand", "OpenStarbound"}, + {"openProtocolVersion", OpenProtocolVersion } + }; connection.pushSingle(std::move(clientConnect)); connection.sendAll(timeout); @@ -134,9 +144,6 @@ Maybe UniverseClient::connect(UniverseConnection connection, bool allowA packet = connection.pullSingle(); } - NetCompatibilityRules compatibilityRules; - compatibilityRules.isLegacy = legacyServer; - if (auto success = as(packet)) { m_universeClock = make_shared(); m_clientContext = make_shared(success->serverUuid, m_mainPlayer->uuid()); diff --git a/source/game/StarUniverseServer.cpp b/source/game/StarUniverseServer.cpp index 09cfdc8..6961ce4 100644 --- a/source/game/StarUniverseServer.cpp +++ b/source/game/StarUniverseServer.cpp @@ -1577,7 +1577,8 @@ void UniverseServer::acceptConnection(UniverseConnection connection, Maybeinfo = JsonObject{ - {"compression", NetCompressionModeNames.getRight(compressionMode)} + {"compression", NetCompressionModeNames.getRight(compressionMode)}, + {"openProtocolVersion", OpenProtocolVersion} }; } connection.pushSingle(protocolResponse); @@ -1674,7 +1675,10 @@ void UniverseServer::acceptConnection(UniverseConnection connection, MaybeplayerName, remoteAddressString); + NetCompatibilityRules netRules(legacyClient ? LegacyVersion : 1); if (Json& info = clientConnect->info) { + if (auto openProtocolVersion = info.optUInt("openProtocolVersion")) + netRules.setVersion(*openProtocolVersion); if (Json brand = info.get("brand", "custom")) connectionLog += strf(" ({} client)", brand.toString()); if (info.getBool("legacy", false)) @@ -1701,7 +1705,6 @@ void UniverseServer::acceptConnection(UniverseConnection connection, Maybe(clientId, remoteAddress, netRules, clientConnect->playerUuid, clientConnect->playerName, clientConnect->playerSpecies, administrator, clientConnect->shipChunks); m_clients.add(clientId, clientContext); diff --git a/source/game/StarWorldClient.cpp b/source/game/StarWorldClient.cpp index aecb77a..b18127e 100644 --- a/source/game/StarWorldClient.cpp +++ b/source/game/StarWorldClient.cpp @@ -1230,7 +1230,7 @@ void WorldClient::update(float dt) { queueUpdatePackets(m_entityUpdateTimer.wrapTick(dt)); - if ((!m_clientState.netCompatibilityRules().isLegacy && m_currentStep % 3 == 0) || m_pingTime.isNothing()) { + if ((!m_clientState.netCompatibilityRules().isLegacy() && m_currentStep % 3 == 0) || m_pingTime.isNothing()) { m_pingTime = Time::monotonicMilliseconds(); m_outgoingPackets.append(make_shared(*m_pingTime)); } diff --git a/source/game/StarWorldServer.cpp b/source/game/StarWorldServer.cpp index a2df77b..fbc23a9 100644 --- a/source/game/StarWorldServer.cpp +++ b/source/game/StarWorldServer.cpp @@ -692,7 +692,6 @@ void WorldServer::update(float dt) { queueUpdatePackets(pair.first, sendRemoteUpdates); } m_netStateCache.clear(); - m_legacyNetStateCache.clear(); for (auto& pair : m_clientInfo) pair.second->pendingForward = false; @@ -1872,7 +1871,7 @@ void WorldServer::queueUpdatePackets(ConnectionId clientId, bool sendRemoteUpdat if (auto version = clientInfo->clientSlavesNetVersion.ptr(entityId)) { if (auto updateSetPacket = updateSetPackets.value(connectionId)) { auto pair = make_pair(entityId, *version); - auto& cache = netRules.isLegacy ? m_legacyNetStateCache : m_netStateCache; + auto& cache = m_netStateCache[netRules]; auto i = cache.find(pair); if (i == cache.end()) i = cache.insert(pair, monitoredEntity->writeNetState(*version, netRules)).first; diff --git a/source/game/StarWorldServer.hpp b/source/game/StarWorldServer.hpp index a87f72d..ea650ac 100644 --- a/source/game/StarWorldServer.hpp +++ b/source/game/StarWorldServer.hpp @@ -374,8 +374,7 @@ private: CollisionGenerator m_collisionGenerator; List m_workingCollisionBlocks; - HashMap, pair> m_netStateCache; - HashMap, pair> m_legacyNetStateCache; + HashMap, pair>> m_netStateCache; OrderedHashMap> m_clientInfo; GameTimer m_entityUpdateTimer; From 3aedd5ae915976dffce90ee4ba125fcb33d2d323 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Wed, 11 Sep 2024 18:28:41 +1000 Subject: [PATCH 008/181] Update build.yml --- .github/workflows/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 60097c8..3b72968 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,6 +3,10 @@ name: Build on: workflow_dispatch: + push: + branches: + - "*" + pull_request: branches: - "*" From a98ff51ef7384f9e7d51e821880e9420c8110cb6 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Wed, 11 Sep 2024 18:29:52 +1000 Subject: [PATCH 009/181] trigger build --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3b72968..33ba3a5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,7 +5,7 @@ on: push: branches: - - "*" + - "*" pull_request: branches: From 3c4a2eb71eea73c7e505ab631a1abc484f9e7b92 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Wed, 11 Sep 2024 19:52:01 +1000 Subject: [PATCH 010/181] tooltip stuff --- source/core/StarFont.cpp | 2 +- source/core/StarImageProcessing.cpp | 2 +- source/windowing/StarPaneManager.cpp | 44 +++++++++++++--------------- source/windowing/StarPaneManager.hpp | 7 ++--- 4 files changed, 26 insertions(+), 29 deletions(-) diff --git a/source/core/StarFont.cpp b/source/core/StarFont.cpp index 07a6265..b0d20fc 100644 --- a/source/core/StarFont.cpp +++ b/source/core/StarFont.cpp @@ -135,7 +135,7 @@ tuple Font::render(String::Char c) { } } } - } else if (colored = slot->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) { + } else if (colored = (slot->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA)) { unsigned bpp = image.bytesPerPixel(); uint8_t* data = image.data() + bpp + ((image.width() * (image.height() - 2)) * bpp); // offset by 1 pixel as it's padded for (size_t y = 0; y != height; ++y) { diff --git a/source/core/StarImageProcessing.cpp b/source/core/StarImageProcessing.cpp index 6d2c51d..390f600 100644 --- a/source/core/StarImageProcessing.cpp +++ b/source/core/StarImageProcessing.cpp @@ -214,7 +214,7 @@ ImageOperation imageOperationFromString(StringView string) { else // we're in A of A=B. In vanilla only A=B pairs are evaluated, so only throw an error if B is also there. return operation; - if (which = !which) + if ((which = !which)) operation.colorReplaceMap[*(Vec4B*)&a] = *(Vec4B*)&b; hexLen = 0; diff --git a/source/windowing/StarPaneManager.cpp b/source/windowing/StarPaneManager.cpp index 0bdc159..d8a727a 100644 --- a/source/windowing/StarPaneManager.cpp +++ b/source/windowing/StarPaneManager.cpp @@ -17,11 +17,9 @@ EnumMap const PaneLayerNames{ PaneManager::PaneManager() : m_context(GuiContext::singletonPtr()), m_prevInterfaceScale(1) { auto assets = Root::singleton().assets(); - m_tooltipMouseoverTime = assets->json("/panes.config:tooltipMouseoverTime").toFloat(); m_tooltipMouseoverRadius = assets->json("/panes.config:tooltipMouseoverRadius").toFloat(); m_tooltipMouseOffset = jsonToVec2I(assets->json("/panes.config:tooltipMouseoverOffset")); - - m_tooltipShowTimer = m_tooltipMouseoverTime; + m_tooltipShowTimer = GameTimer(assets->json("/panes.config:tooltipMouseoverTime").toFloat()); } void PaneManager::displayPane(PaneLayer paneLayer, PanePtr const& pane, DismissCallback onDismiss) { @@ -124,7 +122,9 @@ PanePtr PaneManager::getPaneAt(Set const& paneLayers, Vec2I const& po PanePtr PaneManager::getPaneAt(Vec2I const& position) const { for (auto const& layerPair : m_displayedPanes) { for (auto const& panePair : layerPair.second) { - if (panePair.first->inWindow(position) && panePair.first->active()) + if (panePair.first != m_activeTooltip + && panePair.first->inWindow(position) + && panePair.first->active()) return panePair.first; } } @@ -185,12 +185,12 @@ bool PaneManager::sendInputEvent(InputEvent const& event) { } if (event.is()) { - m_tooltipShowTimer = m_tooltipMouseoverTime; + m_tooltipShowTimer.reset(); if (m_activeTooltip) { dismiss(m_activeTooltip); m_activeTooltip.reset(); m_tooltipParentPane.reset(); - m_tooltipShowTimer = m_tooltipMouseoverTime; + m_tooltipShowTimer.reset(); } } @@ -270,29 +270,27 @@ void PaneManager::render() { } void PaneManager::update(float dt) { - m_tooltipShowTimer -= GlobalTimestep; - if (m_tooltipParentPane.expired()) - m_tooltipParentPane.reset(); + auto newTooltipParentPane = getPaneAt(m_tooltipLastMousePos); - bool removeTooltip = vmag(m_tooltipInitialPosition - m_tooltipLastMousePos) > m_tooltipMouseoverRadius - || m_tooltipParentPane.expired() || m_tooltipParentPane.lock()->inWindow(m_tooltipLastMousePos); + bool updateTooltip = m_tooltipShowTimer.tick(dt) || (m_activeTooltip && ( + vmag(m_tooltipInitialPosition - m_tooltipLastMousePos) > m_tooltipMouseoverRadius + || m_tooltipParentPane != newTooltipParentPane + || !m_tooltipParentPane->inWindow(m_tooltipLastMousePos))); - if (removeTooltip) { - dismiss(m_activeTooltip); - m_activeTooltip.reset(); - m_tooltipParentPane.reset(); - } + if (updateTooltip) { + if (m_activeTooltip) { + dismiss(m_activeTooltip); + m_activeTooltip.reset(); + m_tooltipParentPane.reset(); + } - // Scan for a new tooltip if we just removed the old one, or the show timer has expired - if (removeTooltip || (m_tooltipShowTimer < 0 && !m_activeTooltip)) { - if (auto parentPane = getPaneAt(m_tooltipLastMousePos)) { - if (auto tooltip = parentPane->createTooltip(m_tooltipLastMousePos)) { + m_tooltipShowTimer.reset(); + if (newTooltipParentPane) { + if (auto tooltip = newTooltipParentPane->createTooltip(m_tooltipLastMousePos)) { m_activeTooltip = std::move(tooltip); - m_tooltipParentPane = std::move(parentPane); + m_tooltipParentPane = std::move(newTooltipParentPane); m_tooltipInitialPosition = m_tooltipLastMousePos; displayPane(PaneLayer::Tooltip, m_activeTooltip); - } else { - m_tooltipShowTimer = m_tooltipMouseoverTime; } } } diff --git a/source/windowing/StarPaneManager.hpp b/source/windowing/StarPaneManager.hpp index b6d1032..3d507f3 100644 --- a/source/windowing/StarPaneManager.hpp +++ b/source/windowing/StarPaneManager.hpp @@ -3,6 +3,7 @@ #include "StarPane.hpp" #include "StarOrderedMap.hpp" #include "StarBiMap.hpp" +#include "StarGameTimers.hpp" namespace Star { @@ -92,15 +93,13 @@ private: WidgetPtr m_backgroundWidget; - float m_tooltipMouseoverTime; float m_tooltipMouseoverRadius; Vec2I m_tooltipMouseOffset; - - float m_tooltipShowTimer; + GameTimer m_tooltipShowTimer; Vec2I m_tooltipLastMousePos; Vec2I m_tooltipInitialPosition; PanePtr m_activeTooltip; - PaneWeakPtr m_tooltipParentPane; + PanePtr m_tooltipParentPane; }; } From ba9335f801bb441501a27afd2755ef4c1aff17cb Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 12 Sep 2024 23:03:15 +1000 Subject: [PATCH 011/181] Update StarFont.cpp --- source/core/StarFont.cpp | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/source/core/StarFont.cpp b/source/core/StarFont.cpp index b0d20fc..d854d52 100644 --- a/source/core/StarFont.cpp +++ b/source/core/StarFont.cpp @@ -30,8 +30,6 @@ FTContext ftContext; struct FontImpl { FT_Face face; - String::Char loadedChar = 0; - unsigned renderedPixelSize = 0; }; FontPtr Font::loadFont(String const& fileName, unsigned pixelSize) { @@ -84,8 +82,7 @@ unsigned Font::width(String::Char c) { if (auto width = m_widthCache.maybe({c, m_pixelSize})) { return *width; } else { - if (m_fontImpl->loadedChar != c) - FT_Load_Char(m_fontImpl->face, m_fontImpl->loadedChar = c, FontLoadFlags); + FT_Load_Char(m_fontImpl->face, c, FontLoadFlags); unsigned newWidth = (m_fontImpl->face->glyph->linearHoriAdvance + 32768) / 65536; m_widthCache.insert({c, m_pixelSize}, newWidth); return newWidth; @@ -98,19 +95,11 @@ tuple Font::render(String::Char c) { throw FontException("Font::render called on uninitialized font."); FT_Face face = m_fontImpl->face; + if (FT_Load_Glyph(face, FT_Get_Char_Index(face, c), FontLoadFlags) != 0) + return {}; - if (m_fontImpl->loadedChar != c) { - if (FT_Load_Glyph(face, FT_Get_Char_Index(face, m_fontImpl->loadedChar = c), FontLoadFlags) != 0) - return {}; - - m_fontImpl->renderedPixelSize = 0; - } - - if (m_fontImpl->renderedPixelSize != m_pixelSize) { - m_fontImpl->renderedPixelSize = m_pixelSize; - if (FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL) != 0) - return {}; - } + if (FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL) != 0) + return {}; FT_GlyphSlot slot = face->glyph; if (!slot->bitmap.buffer) From e8d59f9c2b51859f214a84a47583e0fae5aab5b8 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 12 Sep 2024 23:06:13 +1000 Subject: [PATCH 012/181] fix windows pread and pwrite bug reading without a byte offset specified can affect absolute reads afterward, this is a workaround (thanks windows...) --- source/core/StarFile_windows.cpp | 10 ++++++++++ source/core/StarImage.cpp | 7 +++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/source/core/StarFile_windows.cpp b/source/core/StarFile_windows.cpp index 0b5c286..d9719b1 100644 --- a/source/core/StarFile_windows.cpp +++ b/source/core/StarFile_windows.cpp @@ -377,7 +377,12 @@ size_t File::pread(void* f, char* data, size_t len, StreamOffset position) { HANDLE file = (HANDLE)f; DWORD numRead = 0; OVERLAPPED overlapped = makeOverlapped(position); + + StreamOffset pos = ftell(f); + if (pos != 0) fseek(f, 0, IOSeek::Absolute); int ret = ReadFile(file, data, len, &numRead, &overlapped); + if (pos != 0) fseek(f, pos, IOSeek::Absolute); + if (ret == 0) { auto err = GetLastError(); if (err != ERROR_IO_PENDING) @@ -391,7 +396,12 @@ size_t File::pwrite(void* f, char const* data, size_t len, StreamOffset position HANDLE file = (HANDLE)f; DWORD numWritten = 0; OVERLAPPED overlapped = makeOverlapped(position); + + StreamOffset pos = ftell(f); + if (pos != 0) fseek(f, 0, IOSeek::Absolute); int ret = WriteFile(file, data, len, &numWritten, &overlapped); + if (pos != 0) fseek(f, pos, IOSeek::Absolute); + if (ret == 0) { auto err = GetLastError(); if (err != ERROR_IO_PENDING) diff --git a/source/core/StarImage.cpp b/source/core/StarImage.cpp index 52c2370..c7d4962 100644 --- a/source/core/StarImage.cpp +++ b/source/core/StarImage.cpp @@ -18,13 +18,12 @@ void readPngData(png_structp pngPtr, png_bytep data, png_size_t length) { }; bool Image::isPng(IODevicePtr device) { - png_byte header[8]; - device->readAbsolute(0, (char*)header, sizeof(header)); - return !png_sig_cmp(header, 0, sizeof(header)); + png_byte header[8]{}; + return !png_sig_cmp(header, 0, device->readAbsolute(0, (char*)header, sizeof(header))); } Image Image::readPng(IODevicePtr device) { - png_byte header[8]; + png_byte header[8]{}; device->readFull((char*)header, sizeof(header)); if (png_sig_cmp(header, 0, sizeof(header))) From 0da6aa1bd91827b84396cce775fa951ff7ef5934 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 12 Sep 2024 23:31:07 +1000 Subject: [PATCH 013/181] Update StarFile_windows.cpp --- source/core/StarFile_windows.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/source/core/StarFile_windows.cpp b/source/core/StarFile_windows.cpp index d9719b1..54d6c82 100644 --- a/source/core/StarFile_windows.cpp +++ b/source/core/StarFile_windows.cpp @@ -377,12 +377,10 @@ size_t File::pread(void* f, char* data, size_t len, StreamOffset position) { HANDLE file = (HANDLE)f; DWORD numRead = 0; OVERLAPPED overlapped = makeOverlapped(position); - StreamOffset pos = ftell(f); - if (pos != 0) fseek(f, 0, IOSeek::Absolute); + fseek(f, 0, IOSeek::Absolute); int ret = ReadFile(file, data, len, &numRead, &overlapped); - if (pos != 0) fseek(f, pos, IOSeek::Absolute); - + fseek(f, pos, IOSeek::Absolute); if (ret == 0) { auto err = GetLastError(); if (err != ERROR_IO_PENDING) @@ -396,12 +394,10 @@ size_t File::pwrite(void* f, char const* data, size_t len, StreamOffset position HANDLE file = (HANDLE)f; DWORD numWritten = 0; OVERLAPPED overlapped = makeOverlapped(position); - StreamOffset pos = ftell(f); - if (pos != 0) fseek(f, 0, IOSeek::Absolute); + fseek(f, 0, IOSeek::Absolute); int ret = WriteFile(file, data, len, &numWritten, &overlapped); - if (pos != 0) fseek(f, pos, IOSeek::Absolute); - + fseek(f, pos, IOSeek::Absolute); if (ret == 0) { auto err = GetLastError(); if (err != ERROR_IO_PENDING) From 9df51b51b8d0724159e64c28a294d217de036184 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 12 Sep 2024 23:06:13 +1000 Subject: [PATCH 014/181] fix windows pread and pwrite bug reading without a byte offset specified can affect absolute reads afterward, this is a workaround (thanks windows...) --- source/core/StarFile_windows.cpp | 14 +++++++------- source/core/StarImage.cpp | 7 +++---- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/source/core/StarFile_windows.cpp b/source/core/StarFile_windows.cpp index 0b5c286..6352bb7 100644 --- a/source/core/StarFile_windows.cpp +++ b/source/core/StarFile_windows.cpp @@ -18,13 +18,11 @@ namespace Star { -namespace { - OVERLAPPED makeOverlapped(StreamOffset offset) { - OVERLAPPED overlapped = {}; - overlapped.Offset = offset; - overlapped.OffsetHigh = offset >> 32; - return overlapped; - } +OVERLAPPED makeOverlapped(StreamOffset offset) { + OVERLAPPED overlapped = {}; + overlapped.Offset = offset; + overlapped.OffsetHigh = offset >> 32; + return overlapped; } String File::convertDirSeparators(String const& path) { @@ -378,6 +376,7 @@ size_t File::pread(void* f, char* data, size_t len, StreamOffset position) { DWORD numRead = 0; OVERLAPPED overlapped = makeOverlapped(position); int ret = ReadFile(file, data, len, &numRead, &overlapped); + fseek(f, -(StreamOffset)numRead, IOSeek::Relative); if (ret == 0) { auto err = GetLastError(); if (err != ERROR_IO_PENDING) @@ -392,6 +391,7 @@ size_t File::pwrite(void* f, char const* data, size_t len, StreamOffset position DWORD numWritten = 0; OVERLAPPED overlapped = makeOverlapped(position); int ret = WriteFile(file, data, len, &numWritten, &overlapped); + fseek(f, -(StreamOffset)numWritten, IOSeek::Relative); if (ret == 0) { auto err = GetLastError(); if (err != ERROR_IO_PENDING) diff --git a/source/core/StarImage.cpp b/source/core/StarImage.cpp index 52c2370..c7d4962 100644 --- a/source/core/StarImage.cpp +++ b/source/core/StarImage.cpp @@ -18,13 +18,12 @@ void readPngData(png_structp pngPtr, png_bytep data, png_size_t length) { }; bool Image::isPng(IODevicePtr device) { - png_byte header[8]; - device->readAbsolute(0, (char*)header, sizeof(header)); - return !png_sig_cmp(header, 0, sizeof(header)); + png_byte header[8]{}; + return !png_sig_cmp(header, 0, device->readAbsolute(0, (char*)header, sizeof(header))); } Image Image::readPng(IODevicePtr device) { - png_byte header[8]; + png_byte header[8]{}; device->readFull((char*)header, sizeof(header)); if (png_sig_cmp(header, 0, sizeof(header))) From 85fbe0bab02afd4e8afe1b61e72885f6df6b0889 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Fri, 13 Sep 2024 14:56:45 +1000 Subject: [PATCH 015/181] Update StarArmorWearer.cpp --- source/game/StarArmorWearer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/game/StarArmorWearer.cpp b/source/game/StarArmorWearer.cpp index acc3de2..4acce5f 100644 --- a/source/game/StarArmorWearer.cpp +++ b/source/game/StarArmorWearer.cpp @@ -350,13 +350,13 @@ void ArmorWearer::netElementsNeedLoad(bool) { m_backNeedsSync |= itemDatabase->loadItem(m_backCosmeticItemDataNetState.get(), m_backCosmeticItem); if (m_headItemDataNetState.pullUpdated()) - m_headNeedsSync |= !m_headCosmeticItem && itemDatabase->loadItem(m_headItemDataNetState.get(), m_headItem); + m_headNeedsSync |= !itemDatabase->loadItem(m_headItemDataNetState.get(), m_headItem); if (m_chestItemDataNetState.pullUpdated()) - m_chestNeedsSync |= !m_chestCosmeticItem && itemDatabase->loadItem(m_chestItemDataNetState.get(), m_chestItem); + m_chestNeedsSync |= itemDatabase->loadItem(m_chestItemDataNetState.get(), m_chestItem); if (m_legsItemDataNetState.pullUpdated()) - m_legsNeedsSync |= !m_legsCosmeticItem && itemDatabase->loadItem(m_legsItemDataNetState.get(), m_legsItem); + m_legsNeedsSync |= !itemDatabase->loadItem(m_legsItemDataNetState.get(), m_legsItem); if (m_backItemDataNetState.pullUpdated()) - m_backNeedsSync |= !m_backCosmeticItem && itemDatabase->loadItem(m_backItemDataNetState.get(), m_backItem); + m_backNeedsSync |= itemDatabase->loadItem(m_backItemDataNetState.get(), m_backItem); } void ArmorWearer::netElementsNeedStore() { From 253473f32cd641267c46b36d3aaba667ffc7e94c Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Fri, 13 Sep 2024 15:05:28 +1000 Subject: [PATCH 016/181] Update StarWorldServer.cpp --- source/game/StarWorldServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/game/StarWorldServer.cpp b/source/game/StarWorldServer.cpp index fbc23a9..3c053bb 100644 --- a/source/game/StarWorldServer.cpp +++ b/source/game/StarWorldServer.cpp @@ -1885,7 +1885,7 @@ void WorldServer::queueUpdatePackets(ConnectionId clientId, bool sendRemoteUpdat auto firstUpdate = monitoredEntity->writeNetState(0, netRules); clientInfo->clientSlavesNetVersion.add(entityId, firstUpdate.second); clientInfo->outgoingPackets.append(make_shared(monitoredEntity->entityType(), - entityFactory->netStoreEntity(monitoredEntity), std::move(firstUpdate.first), entityId)); + entityFactory->netStoreEntity(monitoredEntity, netRules), std::move(firstUpdate.first), entityId)); } } } From 9dbc4daacc59c1fe506d803d1d8653a395c60822 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Fri, 13 Sep 2024 15:24:13 +1000 Subject: [PATCH 017/181] Update StarWorldServer.cpp --- source/game/StarWorldServer.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source/game/StarWorldServer.cpp b/source/game/StarWorldServer.cpp index 3c053bb..e1e447d 100644 --- a/source/game/StarWorldServer.cpp +++ b/source/game/StarWorldServer.cpp @@ -381,8 +381,9 @@ void WorldServer::handleIncomingPackets(ConnectionId clientId, List c clientInfo->outgoingPackets.append(make_shared(item)); } else if (auto sepacket = as(packet)) { - auto entity = entityFactory->netLoadEntity(sepacket->entityType, std::move(sepacket->storeData)); - entity->readNetState(std::move(sepacket->firstNetState), 0.0f, clientInfo->clientState.netCompatibilityRules()); + auto netRules = clientInfo->clientState.netCompatibilityRules(); + auto entity = entityFactory->netLoadEntity(sepacket->entityType, std::move(sepacket->storeData), netRules); + entity->readNetState(std::move(sepacket->firstNetState), 0.0f, netRules); addEntity(std::move(entity)); } else if (auto rdpacket = as(packet)) { @@ -433,9 +434,9 @@ void WorldServer::handleIncomingPackets(ConnectionId clientId, List c Logger::error("WorldServer received duplicate entity create packet from client, deleting old entity {}", entityCreate->entityId); removeEntity(entityCreate->entityId, false); } - - auto entity = entityFactory->netLoadEntity(entityCreate->entityType, entityCreate->storeData); - entity->readNetState(entityCreate->firstNetState, 0.0f, clientInfo->clientState.netCompatibilityRules()); + auto netRules = clientInfo->clientState.netCompatibilityRules(); + auto entity = entityFactory->netLoadEntity(entityCreate->entityType, entityCreate->storeData, netRules); + entity->readNetState(entityCreate->firstNetState, 0.0f, netRules); entity->init(this, entityCreate->entityId, EntityMode::Slave); m_entityMap->addEntity(entity); From 8155ec671581b051feca4187d5067ddbd149b387 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sat, 14 Sep 2024 15:59:01 +1000 Subject: [PATCH 018/181] protected dungeon ID optimization + /settileprotection improvements --- source/core/StarJsonExtra.hpp | 24 +++++++++---------- source/game/StarCommandProcessor.cpp | 35 +++++++++++++++++++++------- source/game/StarEffectEmitter.cpp | 4 ++-- source/game/StarNetPackets.hpp | 2 +- source/game/StarWorldClient.cpp | 2 +- source/game/StarWorldClient.hpp | 2 +- source/game/StarWorldServer.cpp | 29 ++++++++++++++++++++--- source/game/StarWorldServer.hpp | 5 +++- 8 files changed, 73 insertions(+), 30 deletions(-) diff --git a/source/core/StarJsonExtra.hpp b/source/core/StarJsonExtra.hpp index 2a0ca28..ca5b510 100644 --- a/source/core/StarJsonExtra.hpp +++ b/source/core/StarJsonExtra.hpp @@ -211,32 +211,32 @@ Json jsonFromList(List const& list, Converter&& valueConvert) { return res; } -template -Set jsonToSet(Json const& v) { - return jsonToSet(v, construct()); +template +SetType jsonToSet(Json const& v) { + return jsonToSet(v, construct()); } -template -Set jsonToSet(Json const& v, Converter&& valueConvert) { +template +SetType jsonToSet(Json const& v, Converter&& valueConvert) { if (v.type() != Json::Type::Array) throw JsonException("Json type is not an array in jsonToSet"); - Set res; + SetType res; for (auto const& entry : v.iterateArray()) res.add(valueConvert(entry)); return res; } -template -Json jsonFromSet(Set const& Set) { - return jsonFromSet(Set, construct()); +template +Json jsonFromSet(SetType const& Set) { + return jsonFromSet(Set, construct()); } -template -Json jsonFromSet(Set const& Set, Converter&& valueConvert) { +template +Json jsonFromSet(SetType const& Set, Converter&& valueConvert) { JsonArray res; - for (auto entry : Set) + for (auto& entry : Set) res.push_back(valueConvert(entry)); return res; diff --git a/source/game/StarCommandProcessor.cpp b/source/game/StarCommandProcessor.cpp index b5beb20..7b6915e 100644 --- a/source/game/StarCommandProcessor.cpp +++ b/source/game/StarCommandProcessor.cpp @@ -262,16 +262,33 @@ String CommandProcessor::setTileProtection(ConnectionId connectionId, String con return "Not enough arguments to /settileprotection. Use /settileprotection "; try { - DungeonId dungeonId = lexicalCast(arguments.at(0)); - bool isProtected = lexicalCast(arguments.at(1)); - - bool done = m_universe->executeForClient(connectionId, [dungeonId, isProtected](WorldServer* world, PlayerPtr const&) { - world->setTileProtection(dungeonId, isProtected); - }); - - return done ? "" : "Failed to set block protection."; + bool isProtected = lexicalCast(arguments.takeLast()); + List dungeonIds; + for (auto& banana : arguments) { + auto slices = banana.split(".."); + auto it = slices.begin(); + DungeonId previous = 0; + while (it != slices.end()) { + DungeonId current = lexicalCast(*it); + dungeonIds.append(current); + if (it++ != slices.begin() && previous != current) { + if (current < previous) swap(previous, current); + for (DungeonId id = previous + 1; id != current; ++id) + dungeonIds.append(id); + } + previous = current; + } + } + size_t changed = 0; + if (!m_universe->executeForClient(connectionId, [&](WorldServer* world, PlayerPtr const&) { + changed = world->setTileProtection(dungeonIds, isProtected); + })) { + return "Invalid client state"; + } + String output = strf("{} {} dungeon IDs", isProtected ? "Protected" : "Unprotected", changed); + return changed < dungeonIds.size() ? strf("{} ({} unchanged)", output, dungeonIds.size() - changed) : output; } catch (BadLexicalCast const&) { - return strf("Could not parse /settileprotection parameters. Use /settileprotection ", argumentString); + return strf("Could not parse /settileprotection parameters. Use /settileprotection ", argumentString); } } diff --git a/source/game/StarEffectEmitter.cpp b/source/game/StarEffectEmitter.cpp index ddb0355..28e2986 100644 --- a/source/game/StarEffectEmitter.cpp +++ b/source/game/StarEffectEmitter.cpp @@ -94,14 +94,14 @@ void EffectEmitter::render(RenderCallback* renderCallback) { Json EffectEmitter::toJson() const { return JsonObject{{"activeSources", - jsonFromSet>(m_activeSources.get(), + jsonFromSet>>(m_activeSources.get(), [](pair const& entry) { return JsonObject{{"position", entry.first}, {"source", entry.second}}; })}}; } void EffectEmitter::fromJson(Json const& diskStore) { - m_activeSources.set(jsonToSet>(diskStore.get("activeSources"), + m_activeSources.set(jsonToSet>>(diskStore.get("activeSources"), [](Json const& v) { return pair{v.getString("position"), v.getString("source")}; })); diff --git a/source/game/StarNetPackets.hpp b/source/game/StarNetPackets.hpp index 87a01cf..fc43212 100644 --- a/source/game/StarNetPackets.hpp +++ b/source/game/StarNetPackets.hpp @@ -415,7 +415,7 @@ struct WorldStartPacket : PacketBase { bool respawnInWorld; HashMap dungeonIdGravity; HashMap dungeonIdBreathable; - Set protectedDungeonIds; + StableHashSet protectedDungeonIds; Json worldProperties; ConnectionId clientId; bool localInterpolationMode; diff --git a/source/game/StarWorldClient.cpp b/source/game/StarWorldClient.cpp index ab5f9bf..d5c6bd7 100644 --- a/source/game/StarWorldClient.cpp +++ b/source/game/StarWorldClient.cpp @@ -1435,7 +1435,7 @@ bool WorldClient::isTileProtected(Vec2I const& pos) const { if (!inWorld()) return true; - auto tile = m_tileArray->tile(pos); + auto const& tile = m_tileArray->tile(pos); return m_protectedDungeonIds.contains(tile.dungeonId); } diff --git a/source/game/StarWorldClient.hpp b/source/game/StarWorldClient.hpp index 1616b10..2957661 100644 --- a/source/game/StarWorldClient.hpp +++ b/source/game/StarWorldClient.hpp @@ -367,7 +367,7 @@ private: HashMap m_dungeonIdGravity; HashMap m_dungeonIdBreathable; - Set m_protectedDungeonIds; + StableHashSet m_protectedDungeonIds; HashMap>> m_findUniqueEntityResponses; HashMap> m_entityMessageResponses; diff --git a/source/game/StarWorldServer.cpp b/source/game/StarWorldServer.cpp index e1e447d..c313771 100644 --- a/source/game/StarWorldServer.cpp +++ b/source/game/StarWorldServer.cpp @@ -1190,10 +1190,14 @@ bool WorldServer::isTileProtected(Vec2I const& pos) const { if (!m_tileProtectionEnabled) return false; - auto tile = m_tileArray->tile(pos); + auto const& tile = m_tileArray->tile(pos); return m_protectedDungeonIds.contains(tile.dungeonId); } +bool WorldServer::getTileProtection(DungeonId dungeonId) const { + return m_protectedDungeonIds.contains(dungeonId); +} + void WorldServer::setTileProtection(DungeonId dungeonId, bool isProtected) { bool updated = false; if (isProtected) { @@ -1205,9 +1209,28 @@ void WorldServer::setTileProtection(DungeonId dungeonId, bool isProtected) { if (updated) { for (auto const& pair : m_clientInfo) pair.second->outgoingPackets.append(make_shared(dungeonId, isProtected)); + + Logger::info("Protected dungeonIds for world set to {}", m_protectedDungeonIds); } +} - Logger::info("Protected dungeonIds for world set to {}", m_protectedDungeonIds); +size_t WorldServer::setTileProtection(List const& dungeonIds, bool isProtected) { + List updates; + updates.reserve(dungeonIds.size()); + for (auto const& dungeonId : dungeonIds) + if (isProtected ? m_protectedDungeonIds.add(dungeonId) : m_protectedDungeonIds.remove(dungeonId)) + updates.append(make_shared(dungeonId, isProtected)); + + if (updates.empty()) + return 0; + + for (auto const& pair : m_clientInfo) + pair.second->outgoingPackets.appendAll(updates); + + auto newDungeonIds = m_protectedDungeonIds.values(); + sort(newDungeonIds); + Logger::info("Protected dungeonIds for world set to {}", newDungeonIds); + return updates.size(); } void WorldServer::setTileProtectionEnabled(bool enabled) { @@ -2345,7 +2368,7 @@ void WorldServer::readMetadata() { m_adjustPlayerStart = metadata.getBool("adjustPlayerStart"); m_worldTemplate = make_shared(metadata.get("worldTemplate")); m_centralStructure = WorldStructure(metadata.get("centralStructure")); - m_protectedDungeonIds = jsonToSet(metadata.get("protectedDungeonIds"), mem_fn(&Json::toUInt)); + m_protectedDungeonIds = jsonToSet>(metadata.get("protectedDungeonIds"), mem_fn(&Json::toUInt)); m_worldProperties = metadata.getObject("worldProperties"); m_spawner.setActive(metadata.getBool("spawningEnabled")); diff --git a/source/game/StarWorldServer.hpp b/source/game/StarWorldServer.hpp index ea650ac..21c8e9f 100644 --- a/source/game/StarWorldServer.hpp +++ b/source/game/StarWorldServer.hpp @@ -180,7 +180,10 @@ public: RpcPromise sendEntityMessage(Variant const& entity, String const& message, JsonArray const& args = {}) override; bool isTileProtected(Vec2I const& pos) const override; + bool getTileProtection(DungeonId dungeonId) const; void setTileProtection(DungeonId dungeonId, bool isProtected); + // sets a provided list of DungeonIds all at once and returns how many were changed + size_t setTileProtection(List const& dungeonIds, bool isProtected); // used to globally, temporarily disable protection for certain operations void setTileProtectionEnabled(bool enabled); @@ -396,7 +399,7 @@ private: bool m_generatingDungeon; HashMap m_dungeonIdGravity; HashMap m_dungeonIdBreathable; - Set m_protectedDungeonIds; + StableHashSet m_protectedDungeonIds; bool m_tileProtectionEnabled; HashMap>>> m_entityMessageResponses; From 1dc14b116cede3a635b3ef20bd5dd7b0e494fb73 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:43:06 +1000 Subject: [PATCH 019/181] Update StarJsonExtra.hpp --- source/core/StarJsonExtra.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/StarJsonExtra.hpp b/source/core/StarJsonExtra.hpp index ca5b510..40c3a2f 100644 --- a/source/core/StarJsonExtra.hpp +++ b/source/core/StarJsonExtra.hpp @@ -213,7 +213,7 @@ Json jsonFromList(List const& list, Converter&& valueConvert) { template SetType jsonToSet(Json const& v) { - return jsonToSet(v, construct()); + return jsonToSet(v, construct()); } template From 4d920423694fd80968ff72015534f619595b2d6f Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:46:15 +1000 Subject: [PATCH 020/181] Update StarJsonExtra.hpp --- source/core/StarJsonExtra.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/StarJsonExtra.hpp b/source/core/StarJsonExtra.hpp index 40c3a2f..c8fc185 100644 --- a/source/core/StarJsonExtra.hpp +++ b/source/core/StarJsonExtra.hpp @@ -213,7 +213,7 @@ Json jsonFromList(List const& list, Converter&& valueConvert) { template SetType jsonToSet(Json const& v) { - return jsonToSet(v, construct()); + return jsonToSet(v, construct()); } template From 40299558dd4585adb6066cdade5703be7cf10b76 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sun, 15 Sep 2024 16:41:41 +1000 Subject: [PATCH 021/181] Update StarThread_unix.cpp --- source/core/StarThread_unix.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/core/StarThread_unix.cpp b/source/core/StarThread_unix.cpp index a87ee29..7385ae2 100644 --- a/source/core/StarThread_unix.cpp +++ b/source/core/StarThread_unix.cpp @@ -22,6 +22,10 @@ #define MAX_THREAD_NAMELEN 16 #endif +//#ifndef STAR_SYSTEM_MACOS +//#define STAR_MUTEX_TIMED +//#endif + namespace Star { struct ThreadImpl { @@ -131,7 +135,7 @@ struct MutexImpl { } void lock() { -#ifndef STAR_SYSTEM_MACOS +#ifdef STAR_MUTEX_TIMED timespec ts; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += 60; @@ -210,7 +214,7 @@ struct RecursiveMutexImpl { } void lock() { -#ifndef STAR_SYSTEM_MACOS +#ifdef STAR_MUTEX_TIMED timespec ts; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += 60; From 090441b80aed3c7df45ff1a6d40ed56ee895ad28 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Mon, 16 Sep 2024 23:02:22 +1000 Subject: [PATCH 022/181] make lexical casts (string -> int/float) faster --- source/core/CMakeLists.txt | 1 + source/core/StarLexicalCast.cpp | 13 + source/core/StarLexicalCast.hpp | 58 +- source/extern/CMakeLists.txt | 1 + source/extern/fast_float.h | 3913 ++++++++++++++++++++++++++ source/game/StarCommandProcessor.cpp | 2 +- 6 files changed, 3967 insertions(+), 21 deletions(-) create mode 100644 source/core/StarLexicalCast.cpp create mode 100644 source/extern/fast_float.h diff --git a/source/core/CMakeLists.txt b/source/core/CMakeLists.txt index 2f0c858..fa1d246 100644 --- a/source/core/CMakeLists.txt +++ b/source/core/CMakeLists.txt @@ -160,6 +160,7 @@ SET (star_core_SOURCES StarJsonPatch.cpp StarJsonRpc.cpp StarFormattedJson.cpp + StarLexicalCast.cpp StarListener.cpp StarLogging.cpp StarLua.cpp diff --git a/source/core/StarLexicalCast.cpp b/source/core/StarLexicalCast.cpp new file mode 100644 index 0000000..1387b2e --- /dev/null +++ b/source/core/StarLexicalCast.cpp @@ -0,0 +1,13 @@ +#include "StarLexicalCast.hpp" + +namespace Star { + +void throwLexicalCastError(std::errc ec, const char* first, const char* last) { + StringView str(first, last - first); + if (ec == std::errc::invalid_argument) + throw BadLexicalCast(strf("Lexical cast failed on '{}' (invalid argument)", str)); + else + throw BadLexicalCast(strf("Lexical cast failed on '{}'", str)); +} + +} \ No newline at end of file diff --git a/source/core/StarLexicalCast.hpp b/source/core/StarLexicalCast.hpp index 9c671e9..13c0521 100644 --- a/source/core/StarLexicalCast.hpp +++ b/source/core/StarLexicalCast.hpp @@ -5,40 +5,58 @@ #include "StarStringView.hpp" #include "StarMaybe.hpp" -#include -#include +#include "fast_float.h" namespace Star { STAR_EXCEPTION(BadLexicalCast, StarException); -// Very simple basic lexical cast using stream input. Always operates in the -// "C" locale. +void throwLexicalCastError(std::errc ec, const char* first, const char* last); + template -Maybe maybeLexicalCast(StringView s, std::ios_base::fmtflags flags = std::ios_base::boolalpha) { - Type result; - std::istringstream stream(std::string(s.utf8())); - stream.flags(flags); - stream.imbue(std::locale::classic()); +bool tryLexicalCast(Type& result, const char* first, const char* last) { + auto res = fast_float::from_chars(first, last, result); + return res.ptr == last && (res.ec == std::errc() || res.ec == std::errc::result_out_of_range); +} - if (!(stream >> result)) +template +bool tryLexicalCast(Type& result, String const& s) { + return tryLexicalCast(s.utf8Ptr(), s.utf8Ptr() + s.utf8Size()); +} + +template +bool tryLexicalCast(Type& result, StringView s) { + return tryLexicalCast(s.utf8Ptr(), s.utf8Ptr() + s.utf8Size()); +} + +template +Maybe maybeLexicalCast(const char* first, const char* last) { + Type result{}; + if (tryLexicalCast(result, first, last)) + return result; + else return {}; +} - // Confirm that we read everything out of the stream - char ch; - if (stream >> ch) - return {}; +template +Maybe maybeLexicalCast(StringView s) { + return maybeLexicalCast(s.utf8Ptr(), s.utf8Ptr() + s.utf8Size()); +} + +template +Type lexicalCast(const char* first, const char* last) { + Type result{}; + auto res = fast_float::from_chars(first, last, result); + if ((res.ec != std::errc() && res.ec != std::errc::result_out_of_range) || res.ptr != last) + throwLexicalCastError(res.ec, first, last); + return result; } template -Type lexicalCast(StringView s, std::ios_base::fmtflags flags = std::ios_base::boolalpha) { - auto m = maybeLexicalCast(s, flags); - if (m) - return m.take(); - else - throw BadLexicalCast(strf("Lexical cast failed on '{}'", s)); +Type lexicalCast(StringView s) { + return lexicalCast(s.utf8Ptr(), s.utf8Ptr() + s.utf8Size()); } } diff --git a/source/extern/CMakeLists.txt b/source/extern/CMakeLists.txt index 336ca0d..1fd48e1 100644 --- a/source/extern/CMakeLists.txt +++ b/source/extern/CMakeLists.txt @@ -15,6 +15,7 @@ SET (star_extern_HEADERS fmt/printf.h fmt/ranges.h fmt/std.h + fast_float.h lauxlib.h lua.h lua.hpp diff --git a/source/extern/fast_float.h b/source/extern/fast_float.h new file mode 100644 index 0000000..860001d --- /dev/null +++ b/source/extern/fast_float.h @@ -0,0 +1,3913 @@ +// fast_float by Daniel Lemire +// fast_float by João Paulo Magalhaes +// +// +// with contributions from Eugene Golushkov +// with contributions from Maksim Kita +// with contributions from Marcin Wojdyr +// with contributions from Neal Richardson +// with contributions from Tim Paine +// with contributions from Fabio Pellacini +// with contributions from Lénárd Szolnoki +// with contributions from Jan Pharago +// with contributions from Maya Warrier +// with contributions from Taha Khokhar +// +// +// Licensed under the Apache License, Version 2.0, or the +// MIT License or the Boost License. This file may not be copied, +// modified, or distributed except according to those terms. +// +// MIT License Notice +// +// MIT License +// +// Copyright (c) 2021 The fast_float authors +// +// Permission is hereby granted, free of charge, to any +// person obtaining a copy of this software and associated +// documentation files (the "Software"), to deal in the +// Software without restriction, including without +// limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice +// shall be included in all copies or substantial portions +// of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Apache License (Version 2.0) Notice +// +// Copyright 2021 The fast_float authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// +// BOOST License Notice +// +// Boost Software License - Version 1.0 - August 17th, 2003 +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + +#ifndef FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H +#define FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H + +#ifdef __has_include +#if __has_include() +#include +#endif +#endif + +// Testing for https://wg21.link/N3652, adopted in C++14 +#if __cpp_constexpr >= 201304 +#define FASTFLOAT_CONSTEXPR14 constexpr +#else +#define FASTFLOAT_CONSTEXPR14 +#endif + +#if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L +#define FASTFLOAT_HAS_BIT_CAST 1 +#else +#define FASTFLOAT_HAS_BIT_CAST 0 +#endif + +#if defined(__cpp_lib_is_constant_evaluated) && \ + __cpp_lib_is_constant_evaluated >= 201811L +#define FASTFLOAT_HAS_IS_CONSTANT_EVALUATED 1 +#else +#define FASTFLOAT_HAS_IS_CONSTANT_EVALUATED 0 +#endif + +// Testing for relevant C++20 constexpr library features +#if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED && FASTFLOAT_HAS_BIT_CAST && \ + __cpp_lib_constexpr_algorithms >= 201806L /*For std::copy and std::fill*/ +#define FASTFLOAT_CONSTEXPR20 constexpr +#define FASTFLOAT_IS_CONSTEXPR 1 +#else +#define FASTFLOAT_CONSTEXPR20 +#define FASTFLOAT_IS_CONSTEXPR 0 +#endif + +#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +#define FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE 0 +#else +#define FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE 1 +#endif + +#endif // FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H + +#ifndef FASTFLOAT_FLOAT_COMMON_H +#define FASTFLOAT_FLOAT_COMMON_H + +#include +#include +#include +#include +#include +#include +#ifdef __has_include +#if __has_include() && (__cplusplus > 202002L || _MSVC_LANG > 202002L) +#include +#endif +#endif + +namespace fast_float { + +#define FASTFLOAT_JSONFMT (1 << 5) +#define FASTFLOAT_FORTRANFMT (1 << 6) + +enum chars_format { + scientific = 1 << 0, + fixed = 1 << 2, + hex = 1 << 3, + no_infnan = 1 << 4, + // RFC 8259: https://datatracker.ietf.org/doc/html/rfc8259#section-6 + json = FASTFLOAT_JSONFMT | fixed | scientific | no_infnan, + // Extension of RFC 8259 where, e.g., "inf" and "nan" are allowed. + json_or_infnan = FASTFLOAT_JSONFMT | fixed | scientific, + fortran = FASTFLOAT_FORTRANFMT | fixed | scientific, + general = fixed | scientific +}; + +template struct from_chars_result_t { + UC const *ptr; + std::errc ec; +}; +using from_chars_result = from_chars_result_t; + +template struct parse_options_t { + constexpr explicit parse_options_t(chars_format fmt = chars_format::general, + UC dot = UC('.')) + : format(fmt), decimal_point(dot) {} + + /** Which number formats are accepted */ + chars_format format; + /** The character used as decimal point */ + UC decimal_point; +}; +using parse_options = parse_options_t; + +} // namespace fast_float + +#if FASTFLOAT_HAS_BIT_CAST +#include +#endif + +#if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) || \ + defined(__MINGW64__) || defined(__s390x__) || \ + (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || \ + defined(__PPC64LE__)) || \ + defined(__loongarch64)) +#define FASTFLOAT_64BIT 1 +#elif (defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__arm__) || defined(_M_ARM) || defined(__ppc__) || \ + defined(__MINGW32__) || defined(__EMSCRIPTEN__)) +#define FASTFLOAT_32BIT 1 +#else + // Need to check incrementally, since SIZE_MAX is a size_t, avoid overflow. +// We can never tell the register width, but the SIZE_MAX is a good +// approximation. UINTPTR_MAX and INTPTR_MAX are optional, so avoid them for max +// portability. +#if SIZE_MAX == 0xffff +#error Unknown platform (16-bit, unsupported) +#elif SIZE_MAX == 0xffffffff +#define FASTFLOAT_32BIT 1 +#elif SIZE_MAX == 0xffffffffffffffff +#define FASTFLOAT_64BIT 1 +#else +#error Unknown platform (not 32-bit, not 64-bit?) +#endif +#endif + +#if ((defined(_WIN32) || defined(_WIN64)) && !defined(__clang__)) || \ + (defined(_M_ARM64) && !defined(__MINGW32__)) +#include +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +#define FASTFLOAT_VISUAL_STUDIO 1 +#endif + +#if defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__ +#define FASTFLOAT_IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#elif defined _WIN32 +#define FASTFLOAT_IS_BIG_ENDIAN 0 +#else +#if defined(__APPLE__) || defined(__FreeBSD__) +#include +#elif defined(sun) || defined(__sun) +#include +#elif defined(__MVS__) +#include +#else +#ifdef __has_include +#if __has_include() +#include +#endif //__has_include() +#endif //__has_include +#endif +# +#ifndef __BYTE_ORDER__ +// safe choice +#define FASTFLOAT_IS_BIG_ENDIAN 0 +#endif +# +#ifndef __ORDER_LITTLE_ENDIAN__ +// safe choice +#define FASTFLOAT_IS_BIG_ENDIAN 0 +#endif +# +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define FASTFLOAT_IS_BIG_ENDIAN 0 +#else +#define FASTFLOAT_IS_BIG_ENDIAN 1 +#endif +#endif + +#if defined(__SSE2__) || (defined(FASTFLOAT_VISUAL_STUDIO) && \ + (defined(_M_AMD64) || defined(_M_X64) || \ + (defined(_M_IX86_FP) && _M_IX86_FP == 2))) +#define FASTFLOAT_SSE2 1 +#endif + +#if defined(__aarch64__) || defined(_M_ARM64) +#define FASTFLOAT_NEON 1 +#endif + +#if defined(FASTFLOAT_SSE2) || defined(FASTFLOAT_NEON) +#define FASTFLOAT_HAS_SIMD 1 +#endif + +#if defined(__GNUC__) +// disable -Wcast-align=strict (GCC only) +#define FASTFLOAT_SIMD_DISABLE_WARNINGS \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wcast-align\"") +#else +#define FASTFLOAT_SIMD_DISABLE_WARNINGS +#endif + +#if defined(__GNUC__) +#define FASTFLOAT_SIMD_RESTORE_WARNINGS _Pragma("GCC diagnostic pop") +#else +#define FASTFLOAT_SIMD_RESTORE_WARNINGS +#endif + +#ifdef FASTFLOAT_VISUAL_STUDIO +#define fastfloat_really_inline __forceinline +#else +#define fastfloat_really_inline inline __attribute__((always_inline)) +#endif + +#ifndef FASTFLOAT_ASSERT +#define FASTFLOAT_ASSERT(x) \ + { ((void)(x)); } +#endif + +#ifndef FASTFLOAT_DEBUG_ASSERT +#define FASTFLOAT_DEBUG_ASSERT(x) \ + { ((void)(x)); } +#endif + +// rust style `try!()` macro, or `?` operator +#define FASTFLOAT_TRY(x) \ + { \ + if (!(x)) \ + return false; \ + } + +#define FASTFLOAT_ENABLE_IF(...) \ + typename std::enable_if<(__VA_ARGS__), int>::type + +namespace fast_float { + +fastfloat_really_inline constexpr bool cpp20_and_in_constexpr() { +#if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED + return std::is_constant_evaluated(); +#else + return false; +#endif +} + +template +fastfloat_really_inline constexpr bool is_supported_float_type() { + return std::is_same::value || std::is_same::value +#if __STDCPP_FLOAT32_T__ + || std::is_same::value +#endif +#if __STDCPP_FLOAT64_T__ + || std::is_same::value +#endif + ; +} + +template +fastfloat_really_inline constexpr bool is_supported_char_type() { + return std::is_same::value || std::is_same::value || + std::is_same::value || std::is_same::value; +} + +// Compares two ASCII strings in a case insensitive manner. +template +inline FASTFLOAT_CONSTEXPR14 bool +fastfloat_strncasecmp(UC const *input1, UC const *input2, size_t length) { + char running_diff{0}; + for (size_t i = 0; i < length; ++i) { + running_diff |= (char(input1[i]) ^ char(input2[i])); + } + return (running_diff == 0) || (running_diff == 32); +} + +#ifndef FLT_EVAL_METHOD +#error "FLT_EVAL_METHOD should be defined, please include cfloat." +#endif + +// a pointer and a length to a contiguous block of memory +template struct span { + const T *ptr; + size_t length; + constexpr span(const T *_ptr, size_t _length) : ptr(_ptr), length(_length) {} + constexpr span() : ptr(nullptr), length(0) {} + + constexpr size_t len() const noexcept { return length; } + + FASTFLOAT_CONSTEXPR14 const T &operator[](size_t index) const noexcept { + FASTFLOAT_DEBUG_ASSERT(index < length); + return ptr[index]; + } +}; + +struct value128 { + uint64_t low; + uint64_t high; + constexpr value128(uint64_t _low, uint64_t _high) : low(_low), high(_high) {} + constexpr value128() : low(0), high(0) {} +}; + +/* Helper C++14 constexpr generic implementation of leading_zeroes */ +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 int +leading_zeroes_generic(uint64_t input_num, int last_bit = 0) { + if (input_num & uint64_t(0xffffffff00000000)) { + input_num >>= 32; + last_bit |= 32; + } + if (input_num & uint64_t(0xffff0000)) { + input_num >>= 16; + last_bit |= 16; + } + if (input_num & uint64_t(0xff00)) { + input_num >>= 8; + last_bit |= 8; + } + if (input_num & uint64_t(0xf0)) { + input_num >>= 4; + last_bit |= 4; + } + if (input_num & uint64_t(0xc)) { + input_num >>= 2; + last_bit |= 2; + } + if (input_num & uint64_t(0x2)) { /* input_num >>= 1; */ + last_bit |= 1; + } + return 63 - last_bit; +} + +/* result might be undefined when input_num is zero */ +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 int +leading_zeroes(uint64_t input_num) { + assert(input_num > 0); + if (cpp20_and_in_constexpr()) { + return leading_zeroes_generic(input_num); + } +#ifdef FASTFLOAT_VISUAL_STUDIO +#if defined(_M_X64) || defined(_M_ARM64) + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + _BitScanReverse64(&leading_zero, input_num); + return (int)(63 - leading_zero); +#else + return leading_zeroes_generic(input_num); +#endif +#else + return __builtin_clzll(input_num); +#endif +} + +// slow emulation routine for 32-bit +fastfloat_really_inline constexpr uint64_t emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint64_t +umul128_generic(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = (uint64_t)(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + (uint64_t)(lo < bd); + return lo; +} + +#ifdef FASTFLOAT_32BIT + +// slow emulation routine for 32-bit +#if !defined(__MINGW64__) +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint64_t _umul128(uint64_t ab, + uint64_t cd, + uint64_t *hi) { + return umul128_generic(ab, cd, hi); +} +#endif // !__MINGW64__ + +#endif // FASTFLOAT_32BIT + +// compute 64-bit a*b +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 value128 +full_multiplication(uint64_t a, uint64_t b) { + if (cpp20_and_in_constexpr()) { + value128 answer; + answer.low = umul128_generic(a, b, &answer.high); + return answer; + } + value128 answer; +#if defined(_M_ARM64) && !defined(__MINGW32__) + // ARM64 has native support for 64-bit multiplications, no need to emulate + // But MinGW on ARM64 doesn't have native support for 64-bit multiplications + answer.high = __umulh(a, b); + answer.low = a * b; +#elif defined(FASTFLOAT_32BIT) || \ + (defined(_WIN64) && !defined(__clang__) && !defined(_M_ARM64)) + answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64 +#elif defined(FASTFLOAT_64BIT) && defined(__SIZEOF_INT128__) + __uint128_t r = ((__uint128_t)a) * b; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#else + answer.low = umul128_generic(a, b, &answer.high); +#endif + return answer; +} + +struct adjusted_mantissa { + uint64_t mantissa{0}; + int32_t power2{0}; // a negative value indicates an invalid result + adjusted_mantissa() = default; + constexpr bool operator==(const adjusted_mantissa &o) const { + return mantissa == o.mantissa && power2 == o.power2; + } + constexpr bool operator!=(const adjusted_mantissa &o) const { + return mantissa != o.mantissa || power2 != o.power2; + } +}; + +// Bias so we can get the real exponent with an invalid adjusted_mantissa. +constexpr static int32_t invalid_am_bias = -0x8000; + +// used for binary_format_lookup_tables::max_mantissa +constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5; + +template struct binary_format_lookup_tables; + +template struct binary_format : binary_format_lookup_tables { + using equiv_uint = + typename std::conditional::type; + + static inline constexpr int mantissa_explicit_bits(); + static inline constexpr int minimum_exponent(); + static inline constexpr int infinite_power(); + static inline constexpr int sign_index(); + static inline constexpr int + min_exponent_fast_path(); // used when fegetround() == FE_TONEAREST + static inline constexpr int max_exponent_fast_path(); + static inline constexpr int max_exponent_round_to_even(); + static inline constexpr int min_exponent_round_to_even(); + static inline constexpr uint64_t max_mantissa_fast_path(int64_t power); + static inline constexpr uint64_t + max_mantissa_fast_path(); // used when fegetround() == FE_TONEAREST + static inline constexpr int largest_power_of_ten(); + static inline constexpr int smallest_power_of_ten(); + static inline constexpr T exact_power_of_ten(int64_t power); + static inline constexpr size_t max_digits(); + static inline constexpr equiv_uint exponent_mask(); + static inline constexpr equiv_uint mantissa_mask(); + static inline constexpr equiv_uint hidden_bit_mask(); +}; + +template struct binary_format_lookup_tables { + static constexpr double powers_of_ten[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, + 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22}; + + // Largest integer value v so that (5**index * v) <= 1<<53. + // 0x20000000000000 == 1 << 53 + static constexpr uint64_t max_mantissa[] = { + 0x20000000000000, + 0x20000000000000 / 5, + 0x20000000000000 / (5 * 5), + 0x20000000000000 / (5 * 5 * 5), + 0x20000000000000 / (5 * 5 * 5 * 5), + 0x20000000000000 / (constant_55555), + 0x20000000000000 / (constant_55555 * 5), + 0x20000000000000 / (constant_55555 * 5 * 5), + 0x20000000000000 / (constant_55555 * 5 * 5 * 5), + 0x20000000000000 / (constant_55555 * 5 * 5 * 5 * 5), + 0x20000000000000 / (constant_55555 * constant_55555), + 0x20000000000000 / (constant_55555 * constant_55555 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * 5 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * 5 * 5 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5), + 0x20000000000000 / + (constant_55555 * constant_55555 * constant_55555 * 5 * 5), + 0x20000000000000 / + (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5), + 0x20000000000000 / + (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5), + 0x20000000000000 / + (constant_55555 * constant_55555 * constant_55555 * constant_55555), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 * + constant_55555 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 * + constant_55555 * 5 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 * + constant_55555 * 5 * 5 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 * + constant_55555 * 5 * 5 * 5 * 5)}; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template +constexpr double binary_format_lookup_tables::powers_of_ten[]; + +template +constexpr uint64_t binary_format_lookup_tables::max_mantissa[]; + +#endif + +template struct binary_format_lookup_tables { + static constexpr float powers_of_ten[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, + 1e6f, 1e7f, 1e8f, 1e9f, 1e10f}; + + // Largest integer value v so that (5**index * v) <= 1<<24. + // 0x1000000 == 1<<24 + static constexpr uint64_t max_mantissa[] = { + 0x1000000, + 0x1000000 / 5, + 0x1000000 / (5 * 5), + 0x1000000 / (5 * 5 * 5), + 0x1000000 / (5 * 5 * 5 * 5), + 0x1000000 / (constant_55555), + 0x1000000 / (constant_55555 * 5), + 0x1000000 / (constant_55555 * 5 * 5), + 0x1000000 / (constant_55555 * 5 * 5 * 5), + 0x1000000 / (constant_55555 * 5 * 5 * 5 * 5), + 0x1000000 / (constant_55555 * constant_55555), + 0x1000000 / (constant_55555 * constant_55555 * 5)}; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template +constexpr float binary_format_lookup_tables::powers_of_ten[]; + +template +constexpr uint64_t binary_format_lookup_tables::max_mantissa[]; + +#endif + +template <> +inline constexpr int binary_format::min_exponent_fast_path() { +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + return 0; +#else + return -22; +#endif +} + +template <> +inline constexpr int binary_format::min_exponent_fast_path() { +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + return 0; +#else + return -10; +#endif +} + +template <> +inline constexpr int binary_format::mantissa_explicit_bits() { + return 52; +} +template <> +inline constexpr int binary_format::mantissa_explicit_bits() { + return 23; +} + +template <> +inline constexpr int binary_format::max_exponent_round_to_even() { + return 23; +} + +template <> +inline constexpr int binary_format::max_exponent_round_to_even() { + return 10; +} + +template <> +inline constexpr int binary_format::min_exponent_round_to_even() { + return -4; +} + +template <> +inline constexpr int binary_format::min_exponent_round_to_even() { + return -17; +} + +template <> inline constexpr int binary_format::minimum_exponent() { + return -1023; +} +template <> inline constexpr int binary_format::minimum_exponent() { + return -127; +} + +template <> inline constexpr int binary_format::infinite_power() { + return 0x7FF; +} +template <> inline constexpr int binary_format::infinite_power() { + return 0xFF; +} + +template <> inline constexpr int binary_format::sign_index() { + return 63; +} +template <> inline constexpr int binary_format::sign_index() { + return 31; +} + +template <> +inline constexpr int binary_format::max_exponent_fast_path() { + return 22; +} +template <> +inline constexpr int binary_format::max_exponent_fast_path() { + return 10; +} + +template <> +inline constexpr uint64_t binary_format::max_mantissa_fast_path() { + return uint64_t(2) << mantissa_explicit_bits(); +} +template <> +inline constexpr uint64_t +binary_format::max_mantissa_fast_path(int64_t power) { + // caller is responsible to ensure that + // power >= 0 && power <= 22 + // + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)max_mantissa[0], max_mantissa[power]; +} +template <> +inline constexpr uint64_t binary_format::max_mantissa_fast_path() { + return uint64_t(2) << mantissa_explicit_bits(); +} +template <> +inline constexpr uint64_t +binary_format::max_mantissa_fast_path(int64_t power) { + // caller is responsible to ensure that + // power >= 0 && power <= 10 + // + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)max_mantissa[0], max_mantissa[power]; +} + +template <> +inline constexpr double +binary_format::exact_power_of_ten(int64_t power) { + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)powers_of_ten[0], powers_of_ten[power]; +} +template <> +inline constexpr float binary_format::exact_power_of_ten(int64_t power) { + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)powers_of_ten[0], powers_of_ten[power]; +} + +template <> inline constexpr int binary_format::largest_power_of_ten() { + return 308; +} +template <> inline constexpr int binary_format::largest_power_of_ten() { + return 38; +} + +template <> +inline constexpr int binary_format::smallest_power_of_ten() { + return -342; +} +template <> inline constexpr int binary_format::smallest_power_of_ten() { + return -64; +} + +template <> inline constexpr size_t binary_format::max_digits() { + return 769; +} +template <> inline constexpr size_t binary_format::max_digits() { + return 114; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::exponent_mask() { + return 0x7F800000; +} +template <> +inline constexpr binary_format::equiv_uint +binary_format::exponent_mask() { + return 0x7FF0000000000000; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::mantissa_mask() { + return 0x007FFFFF; +} +template <> +inline constexpr binary_format::equiv_uint +binary_format::mantissa_mask() { + return 0x000FFFFFFFFFFFFF; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::hidden_bit_mask() { + return 0x00800000; +} +template <> +inline constexpr binary_format::equiv_uint +binary_format::hidden_bit_mask() { + return 0x0010000000000000; +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +to_float(bool negative, adjusted_mantissa am, T &value) { + using fastfloat_uint = typename binary_format::equiv_uint; + fastfloat_uint word = (fastfloat_uint)am.mantissa; + word |= fastfloat_uint(am.power2) + << binary_format::mantissa_explicit_bits(); + word |= fastfloat_uint(negative) << binary_format::sign_index(); +#if FASTFLOAT_HAS_BIT_CAST + value = std::bit_cast(word); +#else + ::memcpy(&value, &word, sizeof(T)); +#endif +} + +#ifdef FASTFLOAT_SKIP_WHITE_SPACE // disabled by default +template struct space_lut { + static constexpr bool value[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template constexpr bool space_lut::value[]; + +#endif + +inline constexpr bool is_space(uint8_t c) { return space_lut<>::value[c]; } +#endif + +template static constexpr uint64_t int_cmp_zeros() { + static_assert((sizeof(UC) == 1) || (sizeof(UC) == 2) || (sizeof(UC) == 4), + "Unsupported character size"); + return (sizeof(UC) == 1) ? 0x3030303030303030 + : (sizeof(UC) == 2) + ? (uint64_t(UC('0')) << 48 | uint64_t(UC('0')) << 32 | + uint64_t(UC('0')) << 16 | UC('0')) + : (uint64_t(UC('0')) << 32 | UC('0')); +} +template static constexpr int int_cmp_len() { + return sizeof(uint64_t) / sizeof(UC); +} +template static constexpr UC const *str_const_nan() { + return nullptr; +} +template <> constexpr char const *str_const_nan() { return "nan"; } +template <> constexpr wchar_t const *str_const_nan() { return L"nan"; } +template <> constexpr char16_t const *str_const_nan() { + return u"nan"; +} +template <> constexpr char32_t const *str_const_nan() { + return U"nan"; +} +template static constexpr UC const *str_const_inf() { + return nullptr; +} +template <> constexpr char const *str_const_inf() { return "infinity"; } +template <> constexpr wchar_t const *str_const_inf() { + return L"infinity"; +} +template <> constexpr char16_t const *str_const_inf() { + return u"infinity"; +} +template <> constexpr char32_t const *str_const_inf() { + return U"infinity"; +} + +template struct int_luts { + static constexpr uint8_t chdigit[] = { + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, + 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255}; + + static constexpr size_t maxdigits_u64[] = { + 64, 41, 32, 28, 25, 23, 22, 21, 20, 19, 18, 18, 17, 17, 16, 16, 16, 16, + 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13}; + + static constexpr uint64_t min_safe_u64[] = { + 9223372036854775808ull, 12157665459056928801ull, 4611686018427387904, + 7450580596923828125, 4738381338321616896, 3909821048582988049, + 9223372036854775808ull, 12157665459056928801ull, 10000000000000000000ull, + 5559917313492231481, 2218611106740436992, 8650415919381337933, + 2177953337809371136, 6568408355712890625, 1152921504606846976, + 2862423051509815793, 6746640616477458432, 15181127029874798299ull, + 1638400000000000000, 3243919932521508681, 6221821273427820544, + 11592836324538749809ull, 876488338465357824, 1490116119384765625, + 2481152873203736576, 4052555153018976267, 6502111422497947648, + 10260628712958602189ull, 15943230000000000000ull, 787662783788549761, + 1152921504606846976, 1667889514952984961, 2386420683693101056, + 3379220508056640625, 4738381338321616896}; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template constexpr uint8_t int_luts::chdigit[]; + +template constexpr size_t int_luts::maxdigits_u64[]; + +template constexpr uint64_t int_luts::min_safe_u64[]; + +#endif + +template +fastfloat_really_inline constexpr uint8_t ch_to_digit(UC c) { + return int_luts<>::chdigit[static_cast(c)]; +} + +fastfloat_really_inline constexpr size_t max_digits_u64(int base) { + return int_luts<>::maxdigits_u64[base - 2]; +} + +// If a u64 is exactly max_digits_u64() in length, this is +// the value below which it has definitely overflowed. +fastfloat_really_inline constexpr uint64_t min_safe_u64(int base) { + return int_luts<>::min_safe_u64[base - 2]; +} + +} // namespace fast_float + +#endif + + +#ifndef FASTFLOAT_FAST_FLOAT_H +#define FASTFLOAT_FAST_FLOAT_H + + +namespace fast_float { +/** + * This function parses the character sequence [first,last) for a number. It + * parses floating-point numbers expecting a locale-indepent format equivalent + * to what is used by std::strtod in the default ("C") locale. The resulting + * floating-point value is the closest floating-point values (using either float + * or double), using the "round to even" convention for values that would + * otherwise fall right in-between two values. That is, we provide exact parsing + * according to the IEEE standard. + * + * Given a successful parse, the pointer (`ptr`) in the returned value is set to + * point right after the parsed number, and the `value` referenced is set to the + * parsed value. In case of error, the returned `ec` contains a representative + * error, otherwise the default (`std::errc()`) value is stored. + * + * The implementation does not throw and does not allocate memory (e.g., with + * `new` or `malloc`). + * + * Like the C++17 standard, the `fast_float::from_chars` functions take an + * optional last argument of the type `fast_float::chars_format`. It is a bitset + * value: we check whether `fmt & fast_float::chars_format::fixed` and `fmt & + * fast_float::chars_format::scientific` are set to determine whether we allow + * the fixed point and scientific notation respectively. The default is + * `fast_float::chars_format::general` which allows both `fixed` and + * `scientific`. + */ +template ())> +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars(UC const *first, UC const *last, T &value, + chars_format fmt = chars_format::general) noexcept; + +/** + * Like from_chars, but accepts an `options` argument to govern number parsing. + */ +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars_advanced(UC const *first, UC const *last, T &value, + parse_options_t options) noexcept; +/** + * from_chars for integer types. + */ +template ())> +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars(UC const *first, UC const *last, T &value, int base = 10) noexcept; + +} // namespace fast_float +#endif // FASTFLOAT_FAST_FLOAT_H + +#ifndef FASTFLOAT_ASCII_NUMBER_H +#define FASTFLOAT_ASCII_NUMBER_H + +#include +#include +#include +#include +#include +#include + + +#ifdef FASTFLOAT_SSE2 +#include +#endif + +#ifdef FASTFLOAT_NEON +#include +#endif + +namespace fast_float { + +template fastfloat_really_inline constexpr bool has_simd_opt() { +#ifdef FASTFLOAT_HAS_SIMD + return std::is_same::value; +#else + return false; +#endif +} + +// Next function can be micro-optimized, but compilers are entirely +// able to optimize it well. +template +fastfloat_really_inline constexpr bool is_integer(UC c) noexcept { + return !(c > UC('9') || c < UC('0')); +} + +fastfloat_really_inline constexpr uint64_t byteswap(uint64_t val) { + return (val & 0xFF00000000000000) >> 56 | (val & 0x00FF000000000000) >> 40 | + (val & 0x0000FF0000000000) >> 24 | (val & 0x000000FF00000000) >> 8 | + (val & 0x00000000FF000000) << 8 | (val & 0x0000000000FF0000) << 24 | + (val & 0x000000000000FF00) << 40 | (val & 0x00000000000000FF) << 56; +} + +// Read 8 UC into a u64. Truncates UC if not char. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +read8_to_u64(const UC *chars) { + if (cpp20_and_in_constexpr() || !std::is_same::value) { + uint64_t val = 0; + for (int i = 0; i < 8; ++i) { + val |= uint64_t(uint8_t(*chars)) << (i * 8); + ++chars; + } + return val; + } + uint64_t val; + ::memcpy(&val, chars, sizeof(uint64_t)); +#if FASTFLOAT_IS_BIG_ENDIAN == 1 + // Need to read as-if the number was in little-endian order. + val = byteswap(val); +#endif + return val; +} + +#ifdef FASTFLOAT_SSE2 + +fastfloat_really_inline uint64_t simd_read8_to_u64(const __m128i data) { + FASTFLOAT_SIMD_DISABLE_WARNINGS + const __m128i packed = _mm_packus_epi16(data, data); +#ifdef FASTFLOAT_64BIT + return uint64_t(_mm_cvtsi128_si64(packed)); +#else + uint64_t value; + // Visual Studio + older versions of GCC don't support _mm_storeu_si64 + _mm_storel_epi64(reinterpret_cast<__m128i *>(&value), packed); + return value; +#endif + FASTFLOAT_SIMD_RESTORE_WARNINGS +} + +fastfloat_really_inline uint64_t simd_read8_to_u64(const char16_t *chars) { + FASTFLOAT_SIMD_DISABLE_WARNINGS + return simd_read8_to_u64( + _mm_loadu_si128(reinterpret_cast(chars))); + FASTFLOAT_SIMD_RESTORE_WARNINGS +} + +#elif defined(FASTFLOAT_NEON) + +fastfloat_really_inline uint64_t simd_read8_to_u64(const uint16x8_t data) { + FASTFLOAT_SIMD_DISABLE_WARNINGS + uint8x8_t utf8_packed = vmovn_u16(data); + return vget_lane_u64(vreinterpret_u64_u8(utf8_packed), 0); + FASTFLOAT_SIMD_RESTORE_WARNINGS +} + +fastfloat_really_inline uint64_t simd_read8_to_u64(const char16_t *chars) { + FASTFLOAT_SIMD_DISABLE_WARNINGS + return simd_read8_to_u64( + vld1q_u16(reinterpret_cast(chars))); + FASTFLOAT_SIMD_RESTORE_WARNINGS +} + +#endif // FASTFLOAT_SSE2 + +// MSVC SFINAE is broken pre-VS2017 +#if defined(_MSC_VER) && _MSC_VER <= 1900 +template +#else +template ()) = 0> +#endif +// dummy for compile +uint64_t simd_read8_to_u64(UC const *) { + return 0; +} + +// credit @aqrit +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint32_t +parse_eight_digits_unrolled(uint64_t val) { + const uint64_t mask = 0x000000FF000000FF; + const uint64_t mul1 = 0x000F424000000064; // 100 + (1000000ULL << 32) + const uint64_t mul2 = 0x0000271000000001; // 1 + (10000ULL << 32) + val -= 0x3030303030303030; + val = (val * 10) + (val >> 8); // val = (val * 2561) >> 8; + val = (((val & mask) * mul1) + (((val >> 16) & mask) * mul2)) >> 32; + return uint32_t(val); +} + +// Call this if chars are definitely 8 digits. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint32_t +parse_eight_digits_unrolled(UC const *chars) noexcept { + if (cpp20_and_in_constexpr() || !has_simd_opt()) { + return parse_eight_digits_unrolled(read8_to_u64(chars)); // truncation okay + } + return parse_eight_digits_unrolled(simd_read8_to_u64(chars)); +} + +// credit @aqrit +fastfloat_really_inline constexpr bool +is_made_of_eight_digits_fast(uint64_t val) noexcept { + return !((((val + 0x4646464646464646) | (val - 0x3030303030303030)) & + 0x8080808080808080)); +} + +#ifdef FASTFLOAT_HAS_SIMD + +// Call this if chars might not be 8 digits. +// Using this style (instead of is_made_of_eight_digits_fast() then +// parse_eight_digits_unrolled()) ensures we don't load SIMD registers twice. +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool +simd_parse_if_eight_digits_unrolled(const char16_t *chars, + uint64_t &i) noexcept { + if (cpp20_and_in_constexpr()) { + return false; + } +#ifdef FASTFLOAT_SSE2 + FASTFLOAT_SIMD_DISABLE_WARNINGS + const __m128i data = + _mm_loadu_si128(reinterpret_cast(chars)); + + // (x - '0') <= 9 + // http://0x80.pl/articles/simd-parsing-int-sequences.html + const __m128i t0 = _mm_add_epi16(data, _mm_set1_epi16(32720)); + const __m128i t1 = _mm_cmpgt_epi16(t0, _mm_set1_epi16(-32759)); + + if (_mm_movemask_epi8(t1) == 0) { + i = i * 100000000 + parse_eight_digits_unrolled(simd_read8_to_u64(data)); + return true; + } else + return false; + FASTFLOAT_SIMD_RESTORE_WARNINGS +#elif defined(FASTFLOAT_NEON) + FASTFLOAT_SIMD_DISABLE_WARNINGS + const uint16x8_t data = vld1q_u16(reinterpret_cast(chars)); + + // (x - '0') <= 9 + // http://0x80.pl/articles/simd-parsing-int-sequences.html + const uint16x8_t t0 = vsubq_u16(data, vmovq_n_u16('0')); + const uint16x8_t mask = vcltq_u16(t0, vmovq_n_u16('9' - '0' + 1)); + + if (vminvq_u16(mask) == 0xFFFF) { + i = i * 100000000 + parse_eight_digits_unrolled(simd_read8_to_u64(data)); + return true; + } else + return false; + FASTFLOAT_SIMD_RESTORE_WARNINGS +#else + (void)chars; + (void)i; + return false; +#endif // FASTFLOAT_SSE2 +} + +#endif // FASTFLOAT_HAS_SIMD + +// MSVC SFINAE is broken pre-VS2017 +#if defined(_MSC_VER) && _MSC_VER <= 1900 +template +#else +template ()) = 0> +#endif +// dummy for compile +bool simd_parse_if_eight_digits_unrolled(UC const *, uint64_t &) { + return 0; +} + +template ::value) = 0> +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +loop_parse_if_eight_digits(const UC *&p, const UC *const pend, uint64_t &i) { + if (!has_simd_opt()) { + return; + } + while ((std::distance(p, pend) >= 8) && + simd_parse_if_eight_digits_unrolled( + p, i)) { // in rare cases, this will overflow, but that's ok + p += 8; + } +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +loop_parse_if_eight_digits(const char *&p, const char *const pend, + uint64_t &i) { + // optimizes better than parse_if_eight_digits_unrolled() for UC = char. + while ((std::distance(p, pend) >= 8) && + is_made_of_eight_digits_fast(read8_to_u64(p))) { + i = i * 100000000 + + parse_eight_digits_unrolled(read8_to_u64( + p)); // in rare cases, this will overflow, but that's ok + p += 8; + } +} + +enum class parse_error { + no_error, + // [JSON-only] The minus sign must be followed by an integer. + missing_integer_after_sign, + // A sign must be followed by an integer or dot. + missing_integer_or_dot_after_sign, + // [JSON-only] The integer part must not have leading zeros. + leading_zeros_in_integer_part, + // [JSON-only] The integer part must have at least one digit. + no_digits_in_integer_part, + // [JSON-only] If there is a decimal point, there must be digits in the + // fractional part. + no_digits_in_fractional_part, + // The mantissa must have at least one digit. + no_digits_in_mantissa, + // Scientific notation requires an exponential part. + missing_exponential_part, +}; + +template struct parsed_number_string_t { + int64_t exponent{0}; + uint64_t mantissa{0}; + UC const *lastmatch{nullptr}; + bool negative{false}; + bool valid{false}; + bool too_many_digits{false}; + // contains the range of the significant digits + span integer{}; // non-nullable + span fraction{}; // nullable + parse_error error{parse_error::no_error}; +}; + +using byte_span = span; +using parsed_number_string = parsed_number_string_t; + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 parsed_number_string_t +report_parse_error(UC const *p, parse_error error) { + parsed_number_string_t answer; + answer.valid = false; + answer.lastmatch = p; + answer.error = error; + return answer; +} + +// Assuming that you use no more than 19 digits, this will +// parse an ASCII string. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 parsed_number_string_t +parse_number_string(UC const *p, UC const *pend, + parse_options_t options) noexcept { + chars_format const fmt = options.format; + UC const decimal_point = options.decimal_point; + + parsed_number_string_t answer; + answer.valid = false; + answer.too_many_digits = false; + answer.negative = (*p == UC('-')); +#ifdef FASTFLOAT_ALLOWS_LEADING_PLUS // disabled by default + if ((*p == UC('-')) || (!(fmt & FASTFLOAT_JSONFMT) && *p == UC('+'))) { +#else + if (*p == UC('-')) { // C++17 20.19.3.(7.1) explicitly forbids '+' sign here +#endif + ++p; + if (p == pend) { + return report_parse_error( + p, parse_error::missing_integer_or_dot_after_sign); + } + if (fmt & FASTFLOAT_JSONFMT) { + if (!is_integer(*p)) { // a sign must be followed by an integer + return report_parse_error(p, + parse_error::missing_integer_after_sign); + } + } else { + if (!is_integer(*p) && + (*p != + decimal_point)) { // a sign must be followed by an integer or the dot + return report_parse_error( + p, parse_error::missing_integer_or_dot_after_sign); + } + } + } + UC const *const start_digits = p; + + uint64_t i = 0; // an unsigned int avoids signed overflows (which are bad) + + while ((p != pend) && is_integer(*p)) { + // a multiplication by 10 is cheaper than an arbitrary integer + // multiplication + i = 10 * i + + uint64_t(*p - + UC('0')); // might overflow, we will handle the overflow later + ++p; + } + UC const *const end_of_integer_part = p; + int64_t digit_count = int64_t(end_of_integer_part - start_digits); + answer.integer = span(start_digits, size_t(digit_count)); + if (fmt & FASTFLOAT_JSONFMT) { + // at least 1 digit in integer part, without leading zeros + if (digit_count == 0) { + return report_parse_error(p, parse_error::no_digits_in_integer_part); + } + if ((start_digits[0] == UC('0') && digit_count > 1)) { + return report_parse_error(start_digits, + parse_error::leading_zeros_in_integer_part); + } + } + + int64_t exponent = 0; + const bool has_decimal_point = (p != pend) && (*p == decimal_point); + if (has_decimal_point) { + ++p; + UC const *before = p; + // can occur at most twice without overflowing, but let it occur more, since + // for integers with many digits, digit parsing is the primary bottleneck. + loop_parse_if_eight_digits(p, pend, i); + + while ((p != pend) && is_integer(*p)) { + uint8_t digit = uint8_t(*p - UC('0')); + ++p; + i = i * 10 + digit; // in rare cases, this will overflow, but that's ok + } + exponent = before - p; + answer.fraction = span(before, size_t(p - before)); + digit_count -= exponent; + } + if (fmt & FASTFLOAT_JSONFMT) { + // at least 1 digit in fractional part + if (has_decimal_point && exponent == 0) { + return report_parse_error(p, + parse_error::no_digits_in_fractional_part); + } + } else if (digit_count == + 0) { // we must have encountered at least one integer! + return report_parse_error(p, parse_error::no_digits_in_mantissa); + } + int64_t exp_number = 0; // explicit exponential part + if (((fmt & chars_format::scientific) && (p != pend) && + ((UC('e') == *p) || (UC('E') == *p))) || + ((fmt & FASTFLOAT_FORTRANFMT) && (p != pend) && + ((UC('+') == *p) || (UC('-') == *p) || (UC('d') == *p) || + (UC('D') == *p)))) { + UC const *location_of_e = p; + if ((UC('e') == *p) || (UC('E') == *p) || (UC('d') == *p) || + (UC('D') == *p)) { + ++p; + } + bool neg_exp = false; + if ((p != pend) && (UC('-') == *p)) { + neg_exp = true; + ++p; + } else if ((p != pend) && + (UC('+') == + *p)) { // '+' on exponent is allowed by C++17 20.19.3.(7.1) + ++p; + } + if ((p == pend) || !is_integer(*p)) { + if (!(fmt & chars_format::fixed)) { + // The exponential part is invalid for scientific notation, so it must + // be a trailing token for fixed notation. However, fixed notation is + // disabled, so report a scientific notation error. + return report_parse_error(p, parse_error::missing_exponential_part); + } + // Otherwise, we will be ignoring the 'e'. + p = location_of_e; + } else { + while ((p != pend) && is_integer(*p)) { + uint8_t digit = uint8_t(*p - UC('0')); + if (exp_number < 0x10000000) { + exp_number = 10 * exp_number + digit; + } + ++p; + } + if (neg_exp) { + exp_number = -exp_number; + } + exponent += exp_number; + } + } else { + // If it scientific and not fixed, we have to bail out. + if ((fmt & chars_format::scientific) && !(fmt & chars_format::fixed)) { + return report_parse_error(p, parse_error::missing_exponential_part); + } + } + answer.lastmatch = p; + answer.valid = true; + + // If we frequently had to deal with long strings of digits, + // we could extend our code by using a 128-bit integer instead + // of a 64-bit integer. However, this is uncommon. + // + // We can deal with up to 19 digits. + if (digit_count > 19) { // this is uncommon + // It is possible that the integer had an overflow. + // We have to handle the case where we have 0.0000somenumber. + // We need to be mindful of the case where we only have zeroes... + // E.g., 0.000000000...000. + UC const *start = start_digits; + while ((start != pend) && (*start == UC('0') || *start == decimal_point)) { + if (*start == UC('0')) { + digit_count--; + } + start++; + } + + if (digit_count > 19) { + answer.too_many_digits = true; + // Let us start again, this time, avoiding overflows. + // We don't need to check if is_integer, since we use the + // pre-tokenized spans from above. + i = 0; + p = answer.integer.ptr; + UC const *int_end = p + answer.integer.len(); + const uint64_t minimal_nineteen_digit_integer{1000000000000000000}; + while ((i < minimal_nineteen_digit_integer) && (p != int_end)) { + i = i * 10 + uint64_t(*p - UC('0')); + ++p; + } + if (i >= minimal_nineteen_digit_integer) { // We have a big integers + exponent = end_of_integer_part - p + exp_number; + } else { // We have a value with a fractional component. + p = answer.fraction.ptr; + UC const *frac_end = p + answer.fraction.len(); + while ((i < minimal_nineteen_digit_integer) && (p != frac_end)) { + i = i * 10 + uint64_t(*p - UC('0')); + ++p; + } + exponent = answer.fraction.ptr - p + exp_number; + } + // We have now corrected both exponent and i, to a truncated value + } + } + answer.exponent = exponent; + answer.mantissa = i; + return answer; +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 from_chars_result_t +parse_int_string(UC const *p, UC const *pend, T &value, int base) { + from_chars_result_t answer; + + UC const *const first = p; + + bool negative = (*p == UC('-')); + if (!std::is_signed::value && negative) { + answer.ec = std::errc::invalid_argument; + answer.ptr = first; + return answer; + } +#ifdef FASTFLOAT_ALLOWS_LEADING_PLUS // disabled by default + if ((*p == UC('-')) || (*p == UC('+'))) { +#else + if (*p == UC('-')) { +#endif + ++p; + } + + UC const *const start_num = p; + + while (p != pend && *p == UC('0')) { + ++p; + } + + const bool has_leading_zeros = p > start_num; + + UC const *const start_digits = p; + + uint64_t i = 0; + if (base == 10) { + loop_parse_if_eight_digits(p, pend, i); // use SIMD if possible + } + while (p != pend) { + uint8_t digit = ch_to_digit(*p); + if (digit >= base) { + break; + } + i = uint64_t(base) * i + digit; // might overflow, check this later + p++; + } + + size_t digit_count = size_t(p - start_digits); + + if (digit_count == 0) { + if (has_leading_zeros) { + value = 0; + answer.ec = std::errc(); + answer.ptr = p; + } else { + answer.ec = std::errc::invalid_argument; + answer.ptr = first; + } + return answer; + } + + answer.ptr = p; + + // check u64 overflow + size_t max_digits = max_digits_u64(base); + if (digit_count > max_digits) { + answer.ec = std::errc::result_out_of_range; + return answer; + } + // this check can be eliminated for all other types, but they will all require + // a max_digits(base) equivalent + if (digit_count == max_digits && i < min_safe_u64(base)) { + answer.ec = std::errc::result_out_of_range; + return answer; + } + + // check other types overflow + if (!std::is_same::value) { + if (i > uint64_t(std::numeric_limits::max()) + uint64_t(negative)) { + answer.ec = std::errc::result_out_of_range; + return answer; + } + } + + if (negative) { +#ifdef FASTFLOAT_VISUAL_STUDIO +#pragma warning(push) +#pragma warning(disable : 4146) +#endif + // this weird workaround is required because: + // - converting unsigned to signed when its value is greater than signed max + // is UB pre-C++23. + // - reinterpret_casting (~i + 1) would work, but it is not constexpr + // this is always optimized into a neg instruction (note: T is an integer + // type) + value = T(-std::numeric_limits::max() - + T(i - uint64_t(std::numeric_limits::max()))); +#ifdef FASTFLOAT_VISUAL_STUDIO +#pragma warning(pop) +#endif + } else { + value = T(i); + } + + answer.ec = std::errc(); + return answer; +} + +} // namespace fast_float + +#endif + +#ifndef FASTFLOAT_FAST_TABLE_H +#define FASTFLOAT_FAST_TABLE_H + +#include + +namespace fast_float { + +/** + * When mapping numbers from decimal to binary, + * we go from w * 10^q to m * 2^p but we have + * 10^q = 5^q * 2^q, so effectively + * we are trying to match + * w * 2^q * 5^q to m * 2^p. Thus the powers of two + * are not a concern since they can be represented + * exactly using the binary notation, only the powers of five + * affect the binary significand. + */ + +/** + * The smallest non-zero float (binary64) is 2^-1074. + * We take as input numbers of the form w x 10^q where w < 2^64. + * We have that w * 10^-343 < 2^(64-344) 5^-343 < 2^-1076. + * However, we have that + * (2^64-1) * 10^-342 = (2^64-1) * 2^-342 * 5^-342 > 2^-1074. + * Thus it is possible for a number of the form w * 10^-342 where + * w is a 64-bit value to be a non-zero floating-point number. + ********* + * Any number of form w * 10^309 where w>= 1 is going to be + * infinite in binary64 so we never need to worry about powers + * of 5 greater than 308. + */ +template struct powers_template { + + constexpr static int smallest_power_of_five = + binary_format::smallest_power_of_ten(); + constexpr static int largest_power_of_five = + binary_format::largest_power_of_ten(); + constexpr static int number_of_entries = + 2 * (largest_power_of_five - smallest_power_of_five + 1); + // Powers of five from 5^-342 all the way to 5^308 rounded toward one. + constexpr static uint64_t power_of_five_128[number_of_entries] = { + 0xeef453d6923bd65a, 0x113faa2906a13b3f, + 0x9558b4661b6565f8, 0x4ac7ca59a424c507, + 0xbaaee17fa23ebf76, 0x5d79bcf00d2df649, + 0xe95a99df8ace6f53, 0xf4d82c2c107973dc, + 0x91d8a02bb6c10594, 0x79071b9b8a4be869, + 0xb64ec836a47146f9, 0x9748e2826cdee284, + 0xe3e27a444d8d98b7, 0xfd1b1b2308169b25, + 0x8e6d8c6ab0787f72, 0xfe30f0f5e50e20f7, + 0xb208ef855c969f4f, 0xbdbd2d335e51a935, + 0xde8b2b66b3bc4723, 0xad2c788035e61382, + 0x8b16fb203055ac76, 0x4c3bcb5021afcc31, + 0xaddcb9e83c6b1793, 0xdf4abe242a1bbf3d, + 0xd953e8624b85dd78, 0xd71d6dad34a2af0d, + 0x87d4713d6f33aa6b, 0x8672648c40e5ad68, + 0xa9c98d8ccb009506, 0x680efdaf511f18c2, + 0xd43bf0effdc0ba48, 0x212bd1b2566def2, + 0x84a57695fe98746d, 0x14bb630f7604b57, + 0xa5ced43b7e3e9188, 0x419ea3bd35385e2d, + 0xcf42894a5dce35ea, 0x52064cac828675b9, + 0x818995ce7aa0e1b2, 0x7343efebd1940993, + 0xa1ebfb4219491a1f, 0x1014ebe6c5f90bf8, + 0xca66fa129f9b60a6, 0xd41a26e077774ef6, + 0xfd00b897478238d0, 0x8920b098955522b4, + 0x9e20735e8cb16382, 0x55b46e5f5d5535b0, + 0xc5a890362fddbc62, 0xeb2189f734aa831d, + 0xf712b443bbd52b7b, 0xa5e9ec7501d523e4, + 0x9a6bb0aa55653b2d, 0x47b233c92125366e, + 0xc1069cd4eabe89f8, 0x999ec0bb696e840a, + 0xf148440a256e2c76, 0xc00670ea43ca250d, + 0x96cd2a865764dbca, 0x380406926a5e5728, + 0xbc807527ed3e12bc, 0xc605083704f5ecf2, + 0xeba09271e88d976b, 0xf7864a44c633682e, + 0x93445b8731587ea3, 0x7ab3ee6afbe0211d, + 0xb8157268fdae9e4c, 0x5960ea05bad82964, + 0xe61acf033d1a45df, 0x6fb92487298e33bd, + 0x8fd0c16206306bab, 0xa5d3b6d479f8e056, + 0xb3c4f1ba87bc8696, 0x8f48a4899877186c, + 0xe0b62e2929aba83c, 0x331acdabfe94de87, + 0x8c71dcd9ba0b4925, 0x9ff0c08b7f1d0b14, + 0xaf8e5410288e1b6f, 0x7ecf0ae5ee44dd9, + 0xdb71e91432b1a24a, 0xc9e82cd9f69d6150, + 0x892731ac9faf056e, 0xbe311c083a225cd2, + 0xab70fe17c79ac6ca, 0x6dbd630a48aaf406, + 0xd64d3d9db981787d, 0x92cbbccdad5b108, + 0x85f0468293f0eb4e, 0x25bbf56008c58ea5, + 0xa76c582338ed2621, 0xaf2af2b80af6f24e, + 0xd1476e2c07286faa, 0x1af5af660db4aee1, + 0x82cca4db847945ca, 0x50d98d9fc890ed4d, + 0xa37fce126597973c, 0xe50ff107bab528a0, + 0xcc5fc196fefd7d0c, 0x1e53ed49a96272c8, + 0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7a, + 0x9faacf3df73609b1, 0x77b191618c54e9ac, + 0xc795830d75038c1d, 0xd59df5b9ef6a2417, + 0xf97ae3d0d2446f25, 0x4b0573286b44ad1d, + 0x9becce62836ac577, 0x4ee367f9430aec32, + 0xc2e801fb244576d5, 0x229c41f793cda73f, + 0xf3a20279ed56d48a, 0x6b43527578c1110f, + 0x9845418c345644d6, 0x830a13896b78aaa9, + 0xbe5691ef416bd60c, 0x23cc986bc656d553, + 0xedec366b11c6cb8f, 0x2cbfbe86b7ec8aa8, + 0x94b3a202eb1c3f39, 0x7bf7d71432f3d6a9, + 0xb9e08a83a5e34f07, 0xdaf5ccd93fb0cc53, + 0xe858ad248f5c22c9, 0xd1b3400f8f9cff68, + 0x91376c36d99995be, 0x23100809b9c21fa1, + 0xb58547448ffffb2d, 0xabd40a0c2832a78a, + 0xe2e69915b3fff9f9, 0x16c90c8f323f516c, + 0x8dd01fad907ffc3b, 0xae3da7d97f6792e3, + 0xb1442798f49ffb4a, 0x99cd11cfdf41779c, + 0xdd95317f31c7fa1d, 0x40405643d711d583, + 0x8a7d3eef7f1cfc52, 0x482835ea666b2572, + 0xad1c8eab5ee43b66, 0xda3243650005eecf, + 0xd863b256369d4a40, 0x90bed43e40076a82, + 0x873e4f75e2224e68, 0x5a7744a6e804a291, + 0xa90de3535aaae202, 0x711515d0a205cb36, + 0xd3515c2831559a83, 0xd5a5b44ca873e03, + 0x8412d9991ed58091, 0xe858790afe9486c2, + 0xa5178fff668ae0b6, 0x626e974dbe39a872, + 0xce5d73ff402d98e3, 0xfb0a3d212dc8128f, + 0x80fa687f881c7f8e, 0x7ce66634bc9d0b99, + 0xa139029f6a239f72, 0x1c1fffc1ebc44e80, + 0xc987434744ac874e, 0xa327ffb266b56220, + 0xfbe9141915d7a922, 0x4bf1ff9f0062baa8, + 0x9d71ac8fada6c9b5, 0x6f773fc3603db4a9, + 0xc4ce17b399107c22, 0xcb550fb4384d21d3, + 0xf6019da07f549b2b, 0x7e2a53a146606a48, + 0x99c102844f94e0fb, 0x2eda7444cbfc426d, + 0xc0314325637a1939, 0xfa911155fefb5308, + 0xf03d93eebc589f88, 0x793555ab7eba27ca, + 0x96267c7535b763b5, 0x4bc1558b2f3458de, + 0xbbb01b9283253ca2, 0x9eb1aaedfb016f16, + 0xea9c227723ee8bcb, 0x465e15a979c1cadc, + 0x92a1958a7675175f, 0xbfacd89ec191ec9, + 0xb749faed14125d36, 0xcef980ec671f667b, + 0xe51c79a85916f484, 0x82b7e12780e7401a, + 0x8f31cc0937ae58d2, 0xd1b2ecb8b0908810, + 0xb2fe3f0b8599ef07, 0x861fa7e6dcb4aa15, + 0xdfbdcece67006ac9, 0x67a791e093e1d49a, + 0x8bd6a141006042bd, 0xe0c8bb2c5c6d24e0, + 0xaecc49914078536d, 0x58fae9f773886e18, + 0xda7f5bf590966848, 0xaf39a475506a899e, + 0x888f99797a5e012d, 0x6d8406c952429603, + 0xaab37fd7d8f58178, 0xc8e5087ba6d33b83, + 0xd5605fcdcf32e1d6, 0xfb1e4a9a90880a64, + 0x855c3be0a17fcd26, 0x5cf2eea09a55067f, + 0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481e, + 0xd0601d8efc57b08b, 0xf13b94daf124da26, + 0x823c12795db6ce57, 0x76c53d08d6b70858, + 0xa2cb1717b52481ed, 0x54768c4b0c64ca6e, + 0xcb7ddcdda26da268, 0xa9942f5dcf7dfd09, + 0xfe5d54150b090b02, 0xd3f93b35435d7c4c, + 0x9efa548d26e5a6e1, 0xc47bc5014a1a6daf, + 0xc6b8e9b0709f109a, 0x359ab6419ca1091b, + 0xf867241c8cc6d4c0, 0xc30163d203c94b62, + 0x9b407691d7fc44f8, 0x79e0de63425dcf1d, + 0xc21094364dfb5636, 0x985915fc12f542e4, + 0xf294b943e17a2bc4, 0x3e6f5b7b17b2939d, + 0x979cf3ca6cec5b5a, 0xa705992ceecf9c42, + 0xbd8430bd08277231, 0x50c6ff782a838353, + 0xece53cec4a314ebd, 0xa4f8bf5635246428, + 0x940f4613ae5ed136, 0x871b7795e136be99, + 0xb913179899f68584, 0x28e2557b59846e3f, + 0xe757dd7ec07426e5, 0x331aeada2fe589cf, + 0x9096ea6f3848984f, 0x3ff0d2c85def7621, + 0xb4bca50b065abe63, 0xfed077a756b53a9, + 0xe1ebce4dc7f16dfb, 0xd3e8495912c62894, + 0x8d3360f09cf6e4bd, 0x64712dd7abbbd95c, + 0xb080392cc4349dec, 0xbd8d794d96aacfb3, + 0xdca04777f541c567, 0xecf0d7a0fc5583a0, + 0x89e42caaf9491b60, 0xf41686c49db57244, + 0xac5d37d5b79b6239, 0x311c2875c522ced5, + 0xd77485cb25823ac7, 0x7d633293366b828b, + 0x86a8d39ef77164bc, 0xae5dff9c02033197, + 0xa8530886b54dbdeb, 0xd9f57f830283fdfc, + 0xd267caa862a12d66, 0xd072df63c324fd7b, + 0x8380dea93da4bc60, 0x4247cb9e59f71e6d, + 0xa46116538d0deb78, 0x52d9be85f074e608, + 0xcd795be870516656, 0x67902e276c921f8b, + 0x806bd9714632dff6, 0xba1cd8a3db53b6, + 0xa086cfcd97bf97f3, 0x80e8a40eccd228a4, + 0xc8a883c0fdaf7df0, 0x6122cd128006b2cd, + 0xfad2a4b13d1b5d6c, 0x796b805720085f81, + 0x9cc3a6eec6311a63, 0xcbe3303674053bb0, + 0xc3f490aa77bd60fc, 0xbedbfc4411068a9c, + 0xf4f1b4d515acb93b, 0xee92fb5515482d44, + 0x991711052d8bf3c5, 0x751bdd152d4d1c4a, + 0xbf5cd54678eef0b6, 0xd262d45a78a0635d, + 0xef340a98172aace4, 0x86fb897116c87c34, + 0x9580869f0e7aac0e, 0xd45d35e6ae3d4da0, + 0xbae0a846d2195712, 0x8974836059cca109, + 0xe998d258869facd7, 0x2bd1a438703fc94b, + 0x91ff83775423cc06, 0x7b6306a34627ddcf, + 0xb67f6455292cbf08, 0x1a3bc84c17b1d542, + 0xe41f3d6a7377eeca, 0x20caba5f1d9e4a93, + 0x8e938662882af53e, 0x547eb47b7282ee9c, + 0xb23867fb2a35b28d, 0xe99e619a4f23aa43, + 0xdec681f9f4c31f31, 0x6405fa00e2ec94d4, + 0x8b3c113c38f9f37e, 0xde83bc408dd3dd04, + 0xae0b158b4738705e, 0x9624ab50b148d445, + 0xd98ddaee19068c76, 0x3badd624dd9b0957, + 0x87f8a8d4cfa417c9, 0xe54ca5d70a80e5d6, + 0xa9f6d30a038d1dbc, 0x5e9fcf4ccd211f4c, + 0xd47487cc8470652b, 0x7647c3200069671f, + 0x84c8d4dfd2c63f3b, 0x29ecd9f40041e073, + 0xa5fb0a17c777cf09, 0xf468107100525890, + 0xcf79cc9db955c2cc, 0x7182148d4066eeb4, + 0x81ac1fe293d599bf, 0xc6f14cd848405530, + 0xa21727db38cb002f, 0xb8ada00e5a506a7c, + 0xca9cf1d206fdc03b, 0xa6d90811f0e4851c, + 0xfd442e4688bd304a, 0x908f4a166d1da663, + 0x9e4a9cec15763e2e, 0x9a598e4e043287fe, + 0xc5dd44271ad3cdba, 0x40eff1e1853f29fd, + 0xf7549530e188c128, 0xd12bee59e68ef47c, + 0x9a94dd3e8cf578b9, 0x82bb74f8301958ce, + 0xc13a148e3032d6e7, 0xe36a52363c1faf01, + 0xf18899b1bc3f8ca1, 0xdc44e6c3cb279ac1, + 0x96f5600f15a7b7e5, 0x29ab103a5ef8c0b9, + 0xbcb2b812db11a5de, 0x7415d448f6b6f0e7, + 0xebdf661791d60f56, 0x111b495b3464ad21, + 0x936b9fcebb25c995, 0xcab10dd900beec34, + 0xb84687c269ef3bfb, 0x3d5d514f40eea742, + 0xe65829b3046b0afa, 0xcb4a5a3112a5112, + 0x8ff71a0fe2c2e6dc, 0x47f0e785eaba72ab, + 0xb3f4e093db73a093, 0x59ed216765690f56, + 0xe0f218b8d25088b8, 0x306869c13ec3532c, + 0x8c974f7383725573, 0x1e414218c73a13fb, + 0xafbd2350644eeacf, 0xe5d1929ef90898fa, + 0xdbac6c247d62a583, 0xdf45f746b74abf39, + 0x894bc396ce5da772, 0x6b8bba8c328eb783, + 0xab9eb47c81f5114f, 0x66ea92f3f326564, + 0xd686619ba27255a2, 0xc80a537b0efefebd, + 0x8613fd0145877585, 0xbd06742ce95f5f36, + 0xa798fc4196e952e7, 0x2c48113823b73704, + 0xd17f3b51fca3a7a0, 0xf75a15862ca504c5, + 0x82ef85133de648c4, 0x9a984d73dbe722fb, + 0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebba, + 0xcc963fee10b7d1b3, 0x318df905079926a8, + 0xffbbcfe994e5c61f, 0xfdf17746497f7052, + 0x9fd561f1fd0f9bd3, 0xfeb6ea8bedefa633, + 0xc7caba6e7c5382c8, 0xfe64a52ee96b8fc0, + 0xf9bd690a1b68637b, 0x3dfdce7aa3c673b0, + 0x9c1661a651213e2d, 0x6bea10ca65c084e, + 0xc31bfa0fe5698db8, 0x486e494fcff30a62, + 0xf3e2f893dec3f126, 0x5a89dba3c3efccfa, + 0x986ddb5c6b3a76b7, 0xf89629465a75e01c, + 0xbe89523386091465, 0xf6bbb397f1135823, + 0xee2ba6c0678b597f, 0x746aa07ded582e2c, + 0x94db483840b717ef, 0xa8c2a44eb4571cdc, + 0xba121a4650e4ddeb, 0x92f34d62616ce413, + 0xe896a0d7e51e1566, 0x77b020baf9c81d17, + 0x915e2486ef32cd60, 0xace1474dc1d122e, + 0xb5b5ada8aaff80b8, 0xd819992132456ba, + 0xe3231912d5bf60e6, 0x10e1fff697ed6c69, + 0x8df5efabc5979c8f, 0xca8d3ffa1ef463c1, + 0xb1736b96b6fd83b3, 0xbd308ff8a6b17cb2, + 0xddd0467c64bce4a0, 0xac7cb3f6d05ddbde, + 0x8aa22c0dbef60ee4, 0x6bcdf07a423aa96b, + 0xad4ab7112eb3929d, 0x86c16c98d2c953c6, + 0xd89d64d57a607744, 0xe871c7bf077ba8b7, + 0x87625f056c7c4a8b, 0x11471cd764ad4972, + 0xa93af6c6c79b5d2d, 0xd598e40d3dd89bcf, + 0xd389b47879823479, 0x4aff1d108d4ec2c3, + 0x843610cb4bf160cb, 0xcedf722a585139ba, + 0xa54394fe1eedb8fe, 0xc2974eb4ee658828, + 0xce947a3da6a9273e, 0x733d226229feea32, + 0x811ccc668829b887, 0x806357d5a3f525f, + 0xa163ff802a3426a8, 0xca07c2dcb0cf26f7, + 0xc9bcff6034c13052, 0xfc89b393dd02f0b5, + 0xfc2c3f3841f17c67, 0xbbac2078d443ace2, + 0x9d9ba7832936edc0, 0xd54b944b84aa4c0d, + 0xc5029163f384a931, 0xa9e795e65d4df11, + 0xf64335bcf065d37d, 0x4d4617b5ff4a16d5, + 0x99ea0196163fa42e, 0x504bced1bf8e4e45, + 0xc06481fb9bcf8d39, 0xe45ec2862f71e1d6, + 0xf07da27a82c37088, 0x5d767327bb4e5a4c, + 0x964e858c91ba2655, 0x3a6a07f8d510f86f, + 0xbbe226efb628afea, 0x890489f70a55368b, + 0xeadab0aba3b2dbe5, 0x2b45ac74ccea842e, + 0x92c8ae6b464fc96f, 0x3b0b8bc90012929d, + 0xb77ada0617e3bbcb, 0x9ce6ebb40173744, + 0xe55990879ddcaabd, 0xcc420a6a101d0515, + 0x8f57fa54c2a9eab6, 0x9fa946824a12232d, + 0xb32df8e9f3546564, 0x47939822dc96abf9, + 0xdff9772470297ebd, 0x59787e2b93bc56f7, + 0x8bfbea76c619ef36, 0x57eb4edb3c55b65a, + 0xaefae51477a06b03, 0xede622920b6b23f1, + 0xdab99e59958885c4, 0xe95fab368e45eced, + 0x88b402f7fd75539b, 0x11dbcb0218ebb414, + 0xaae103b5fcd2a881, 0xd652bdc29f26a119, + 0xd59944a37c0752a2, 0x4be76d3346f0495f, + 0x857fcae62d8493a5, 0x6f70a4400c562ddb, + 0xa6dfbd9fb8e5b88e, 0xcb4ccd500f6bb952, + 0xd097ad07a71f26b2, 0x7e2000a41346a7a7, + 0x825ecc24c873782f, 0x8ed400668c0c28c8, + 0xa2f67f2dfa90563b, 0x728900802f0f32fa, + 0xcbb41ef979346bca, 0x4f2b40a03ad2ffb9, + 0xfea126b7d78186bc, 0xe2f610c84987bfa8, + 0x9f24b832e6b0f436, 0xdd9ca7d2df4d7c9, + 0xc6ede63fa05d3143, 0x91503d1c79720dbb, + 0xf8a95fcf88747d94, 0x75a44c6397ce912a, + 0x9b69dbe1b548ce7c, 0xc986afbe3ee11aba, + 0xc24452da229b021b, 0xfbe85badce996168, + 0xf2d56790ab41c2a2, 0xfae27299423fb9c3, + 0x97c560ba6b0919a5, 0xdccd879fc967d41a, + 0xbdb6b8e905cb600f, 0x5400e987bbc1c920, + 0xed246723473e3813, 0x290123e9aab23b68, + 0x9436c0760c86e30b, 0xf9a0b6720aaf6521, + 0xb94470938fa89bce, 0xf808e40e8d5b3e69, + 0xe7958cb87392c2c2, 0xb60b1d1230b20e04, + 0x90bd77f3483bb9b9, 0xb1c6f22b5e6f48c2, + 0xb4ecd5f01a4aa828, 0x1e38aeb6360b1af3, + 0xe2280b6c20dd5232, 0x25c6da63c38de1b0, + 0x8d590723948a535f, 0x579c487e5a38ad0e, + 0xb0af48ec79ace837, 0x2d835a9df0c6d851, + 0xdcdb1b2798182244, 0xf8e431456cf88e65, + 0x8a08f0f8bf0f156b, 0x1b8e9ecb641b58ff, + 0xac8b2d36eed2dac5, 0xe272467e3d222f3f, + 0xd7adf884aa879177, 0x5b0ed81dcc6abb0f, + 0x86ccbb52ea94baea, 0x98e947129fc2b4e9, + 0xa87fea27a539e9a5, 0x3f2398d747b36224, + 0xd29fe4b18e88640e, 0x8eec7f0d19a03aad, + 0x83a3eeeef9153e89, 0x1953cf68300424ac, + 0xa48ceaaab75a8e2b, 0x5fa8c3423c052dd7, + 0xcdb02555653131b6, 0x3792f412cb06794d, + 0x808e17555f3ebf11, 0xe2bbd88bbee40bd0, + 0xa0b19d2ab70e6ed6, 0x5b6aceaeae9d0ec4, + 0xc8de047564d20a8b, 0xf245825a5a445275, + 0xfb158592be068d2e, 0xeed6e2f0f0d56712, + 0x9ced737bb6c4183d, 0x55464dd69685606b, + 0xc428d05aa4751e4c, 0xaa97e14c3c26b886, + 0xf53304714d9265df, 0xd53dd99f4b3066a8, + 0x993fe2c6d07b7fab, 0xe546a8038efe4029, + 0xbf8fdb78849a5f96, 0xde98520472bdd033, + 0xef73d256a5c0f77c, 0x963e66858f6d4440, + 0x95a8637627989aad, 0xdde7001379a44aa8, + 0xbb127c53b17ec159, 0x5560c018580d5d52, + 0xe9d71b689dde71af, 0xaab8f01e6e10b4a6, + 0x9226712162ab070d, 0xcab3961304ca70e8, + 0xb6b00d69bb55c8d1, 0x3d607b97c5fd0d22, + 0xe45c10c42a2b3b05, 0x8cb89a7db77c506a, + 0x8eb98a7a9a5b04e3, 0x77f3608e92adb242, + 0xb267ed1940f1c61c, 0x55f038b237591ed3, + 0xdf01e85f912e37a3, 0x6b6c46dec52f6688, + 0x8b61313bbabce2c6, 0x2323ac4b3b3da015, + 0xae397d8aa96c1b77, 0xabec975e0a0d081a, + 0xd9c7dced53c72255, 0x96e7bd358c904a21, + 0x881cea14545c7575, 0x7e50d64177da2e54, + 0xaa242499697392d2, 0xdde50bd1d5d0b9e9, + 0xd4ad2dbfc3d07787, 0x955e4ec64b44e864, + 0x84ec3c97da624ab4, 0xbd5af13bef0b113e, + 0xa6274bbdd0fadd61, 0xecb1ad8aeacdd58e, + 0xcfb11ead453994ba, 0x67de18eda5814af2, + 0x81ceb32c4b43fcf4, 0x80eacf948770ced7, + 0xa2425ff75e14fc31, 0xa1258379a94d028d, + 0xcad2f7f5359a3b3e, 0x96ee45813a04330, + 0xfd87b5f28300ca0d, 0x8bca9d6e188853fc, + 0x9e74d1b791e07e48, 0x775ea264cf55347e, + 0xc612062576589dda, 0x95364afe032a819e, + 0xf79687aed3eec551, 0x3a83ddbd83f52205, + 0x9abe14cd44753b52, 0xc4926a9672793543, + 0xc16d9a0095928a27, 0x75b7053c0f178294, + 0xf1c90080baf72cb1, 0x5324c68b12dd6339, + 0x971da05074da7bee, 0xd3f6fc16ebca5e04, + 0xbce5086492111aea, 0x88f4bb1ca6bcf585, + 0xec1e4a7db69561a5, 0x2b31e9e3d06c32e6, + 0x9392ee8e921d5d07, 0x3aff322e62439fd0, + 0xb877aa3236a4b449, 0x9befeb9fad487c3, + 0xe69594bec44de15b, 0x4c2ebe687989a9b4, + 0x901d7cf73ab0acd9, 0xf9d37014bf60a11, + 0xb424dc35095cd80f, 0x538484c19ef38c95, + 0xe12e13424bb40e13, 0x2865a5f206b06fba, + 0x8cbccc096f5088cb, 0xf93f87b7442e45d4, + 0xafebff0bcb24aafe, 0xf78f69a51539d749, + 0xdbe6fecebdedd5be, 0xb573440e5a884d1c, + 0x89705f4136b4a597, 0x31680a88f8953031, + 0xabcc77118461cefc, 0xfdc20d2b36ba7c3e, + 0xd6bf94d5e57a42bc, 0x3d32907604691b4d, + 0x8637bd05af6c69b5, 0xa63f9a49c2c1b110, + 0xa7c5ac471b478423, 0xfcf80dc33721d54, + 0xd1b71758e219652b, 0xd3c36113404ea4a9, + 0x83126e978d4fdf3b, 0x645a1cac083126ea, + 0xa3d70a3d70a3d70a, 0x3d70a3d70a3d70a4, + 0xcccccccccccccccc, 0xcccccccccccccccd, + 0x8000000000000000, 0x0, + 0xa000000000000000, 0x0, + 0xc800000000000000, 0x0, + 0xfa00000000000000, 0x0, + 0x9c40000000000000, 0x0, + 0xc350000000000000, 0x0, + 0xf424000000000000, 0x0, + 0x9896800000000000, 0x0, + 0xbebc200000000000, 0x0, + 0xee6b280000000000, 0x0, + 0x9502f90000000000, 0x0, + 0xba43b74000000000, 0x0, + 0xe8d4a51000000000, 0x0, + 0x9184e72a00000000, 0x0, + 0xb5e620f480000000, 0x0, + 0xe35fa931a0000000, 0x0, + 0x8e1bc9bf04000000, 0x0, + 0xb1a2bc2ec5000000, 0x0, + 0xde0b6b3a76400000, 0x0, + 0x8ac7230489e80000, 0x0, + 0xad78ebc5ac620000, 0x0, + 0xd8d726b7177a8000, 0x0, + 0x878678326eac9000, 0x0, + 0xa968163f0a57b400, 0x0, + 0xd3c21bcecceda100, 0x0, + 0x84595161401484a0, 0x0, + 0xa56fa5b99019a5c8, 0x0, + 0xcecb8f27f4200f3a, 0x0, + 0x813f3978f8940984, 0x4000000000000000, + 0xa18f07d736b90be5, 0x5000000000000000, + 0xc9f2c9cd04674ede, 0xa400000000000000, + 0xfc6f7c4045812296, 0x4d00000000000000, + 0x9dc5ada82b70b59d, 0xf020000000000000, + 0xc5371912364ce305, 0x6c28000000000000, + 0xf684df56c3e01bc6, 0xc732000000000000, + 0x9a130b963a6c115c, 0x3c7f400000000000, + 0xc097ce7bc90715b3, 0x4b9f100000000000, + 0xf0bdc21abb48db20, 0x1e86d40000000000, + 0x96769950b50d88f4, 0x1314448000000000, + 0xbc143fa4e250eb31, 0x17d955a000000000, + 0xeb194f8e1ae525fd, 0x5dcfab0800000000, + 0x92efd1b8d0cf37be, 0x5aa1cae500000000, + 0xb7abc627050305ad, 0xf14a3d9e40000000, + 0xe596b7b0c643c719, 0x6d9ccd05d0000000, + 0x8f7e32ce7bea5c6f, 0xe4820023a2000000, + 0xb35dbf821ae4f38b, 0xdda2802c8a800000, + 0xe0352f62a19e306e, 0xd50b2037ad200000, + 0x8c213d9da502de45, 0x4526f422cc340000, + 0xaf298d050e4395d6, 0x9670b12b7f410000, + 0xdaf3f04651d47b4c, 0x3c0cdd765f114000, + 0x88d8762bf324cd0f, 0xa5880a69fb6ac800, + 0xab0e93b6efee0053, 0x8eea0d047a457a00, + 0xd5d238a4abe98068, 0x72a4904598d6d880, + 0x85a36366eb71f041, 0x47a6da2b7f864750, + 0xa70c3c40a64e6c51, 0x999090b65f67d924, + 0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d, + 0x82818f1281ed449f, 0xbff8f10e7a8921a4, + 0xa321f2d7226895c7, 0xaff72d52192b6a0d, + 0xcbea6f8ceb02bb39, 0x9bf4f8a69f764490, + 0xfee50b7025c36a08, 0x2f236d04753d5b4, + 0x9f4f2726179a2245, 0x1d762422c946590, + 0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef5, + 0xf8ebad2b84e0d58b, 0xd2e0898765a7deb2, + 0x9b934c3b330c8577, 0x63cc55f49f88eb2f, + 0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fb, + 0xf316271c7fc3908a, 0x8bef464e3945ef7a, + 0x97edd871cfda3a56, 0x97758bf0e3cbb5ac, + 0xbde94e8e43d0c8ec, 0x3d52eeed1cbea317, + 0xed63a231d4c4fb27, 0x4ca7aaa863ee4bdd, + 0x945e455f24fb1cf8, 0x8fe8caa93e74ef6a, + 0xb975d6b6ee39e436, 0xb3e2fd538e122b44, + 0xe7d34c64a9c85d44, 0x60dbbca87196b616, + 0x90e40fbeea1d3a4a, 0xbc8955e946fe31cd, + 0xb51d13aea4a488dd, 0x6babab6398bdbe41, + 0xe264589a4dcdab14, 0xc696963c7eed2dd1, + 0x8d7eb76070a08aec, 0xfc1e1de5cf543ca2, + 0xb0de65388cc8ada8, 0x3b25a55f43294bcb, + 0xdd15fe86affad912, 0x49ef0eb713f39ebe, + 0x8a2dbf142dfcc7ab, 0x6e3569326c784337, + 0xacb92ed9397bf996, 0x49c2c37f07965404, + 0xd7e77a8f87daf7fb, 0xdc33745ec97be906, + 0x86f0ac99b4e8dafd, 0x69a028bb3ded71a3, + 0xa8acd7c0222311bc, 0xc40832ea0d68ce0c, + 0xd2d80db02aabd62b, 0xf50a3fa490c30190, + 0x83c7088e1aab65db, 0x792667c6da79e0fa, + 0xa4b8cab1a1563f52, 0x577001b891185938, + 0xcde6fd5e09abcf26, 0xed4c0226b55e6f86, + 0x80b05e5ac60b6178, 0x544f8158315b05b4, + 0xa0dc75f1778e39d6, 0x696361ae3db1c721, + 0xc913936dd571c84c, 0x3bc3a19cd1e38e9, + 0xfb5878494ace3a5f, 0x4ab48a04065c723, + 0x9d174b2dcec0e47b, 0x62eb0d64283f9c76, + 0xc45d1df942711d9a, 0x3ba5d0bd324f8394, + 0xf5746577930d6500, 0xca8f44ec7ee36479, + 0x9968bf6abbe85f20, 0x7e998b13cf4e1ecb, + 0xbfc2ef456ae276e8, 0x9e3fedd8c321a67e, + 0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101e, + 0x95d04aee3b80ece5, 0xbba1f1d158724a12, + 0xbb445da9ca61281f, 0x2a8a6e45ae8edc97, + 0xea1575143cf97226, 0xf52d09d71a3293bd, + 0x924d692ca61be758, 0x593c2626705f9c56, + 0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836c, + 0xe498f455c38b997a, 0xb6dfb9c0f956447, + 0x8edf98b59a373fec, 0x4724bd4189bd5eac, + 0xb2977ee300c50fe7, 0x58edec91ec2cb657, + 0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ed, + 0x8b865b215899f46c, 0xbd79e0d20082ee74, + 0xae67f1e9aec07187, 0xecd8590680a3aa11, + 0xda01ee641a708de9, 0xe80e6f4820cc9495, + 0x884134fe908658b2, 0x3109058d147fdcdd, + 0xaa51823e34a7eede, 0xbd4b46f0599fd415, + 0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91a, + 0x850fadc09923329e, 0x3e2cf6bc604ddb0, + 0xa6539930bf6bff45, 0x84db8346b786151c, + 0xcfe87f7cef46ff16, 0xe612641865679a63, + 0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07e, + 0xa26da3999aef7749, 0xe3be5e330f38f09d, + 0xcb090c8001ab551c, 0x5cadf5bfd3072cc5, + 0xfdcb4fa002162a63, 0x73d9732fc7c8f7f6, + 0x9e9f11c4014dda7e, 0x2867e7fddcdd9afa, + 0xc646d63501a1511d, 0xb281e1fd541501b8, + 0xf7d88bc24209a565, 0x1f225a7ca91a4226, + 0x9ae757596946075f, 0x3375788de9b06958, + 0xc1a12d2fc3978937, 0x52d6b1641c83ae, + 0xf209787bb47d6b84, 0xc0678c5dbd23a49a, + 0x9745eb4d50ce6332, 0xf840b7ba963646e0, + 0xbd176620a501fbff, 0xb650e5a93bc3d898, + 0xec5d3fa8ce427aff, 0xa3e51f138ab4cebe, + 0x93ba47c980e98cdf, 0xc66f336c36b10137, + 0xb8a8d9bbe123f017, 0xb80b0047445d4184, + 0xe6d3102ad96cec1d, 0xa60dc059157491e5, + 0x9043ea1ac7e41392, 0x87c89837ad68db2f, + 0xb454e4a179dd1877, 0x29babe4598c311fb, + 0xe16a1dc9d8545e94, 0xf4296dd6fef3d67a, + 0x8ce2529e2734bb1d, 0x1899e4a65f58660c, + 0xb01ae745b101e9e4, 0x5ec05dcff72e7f8f, + 0xdc21a1171d42645d, 0x76707543f4fa1f73, + 0x899504ae72497eba, 0x6a06494a791c53a8, + 0xabfa45da0edbde69, 0x487db9d17636892, + 0xd6f8d7509292d603, 0x45a9d2845d3c42b6, + 0x865b86925b9bc5c2, 0xb8a2392ba45a9b2, + 0xa7f26836f282b732, 0x8e6cac7768d7141e, + 0xd1ef0244af2364ff, 0x3207d795430cd926, + 0x8335616aed761f1f, 0x7f44e6bd49e807b8, + 0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a6, + 0xcd036837130890a1, 0x36dba887c37a8c0f, + 0x802221226be55a64, 0xc2494954da2c9789, + 0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6c, + 0xc83553c5c8965d3d, 0x6f92829494e5acc7, + 0xfa42a8b73abbf48c, 0xcb772339ba1f17f9, + 0x9c69a97284b578d7, 0xff2a760414536efb, + 0xc38413cf25e2d70d, 0xfef5138519684aba, + 0xf46518c2ef5b8cd1, 0x7eb258665fc25d69, + 0x98bf2f79d5993802, 0xef2f773ffbd97a61, + 0xbeeefb584aff8603, 0xaafb550ffacfd8fa, + 0xeeaaba2e5dbf6784, 0x95ba2a53f983cf38, + 0x952ab45cfa97a0b2, 0xdd945a747bf26183, + 0xba756174393d88df, 0x94f971119aeef9e4, + 0xe912b9d1478ceb17, 0x7a37cd5601aab85d, + 0x91abb422ccb812ee, 0xac62e055c10ab33a, + 0xb616a12b7fe617aa, 0x577b986b314d6009, + 0xe39c49765fdf9d94, 0xed5a7e85fda0b80b, + 0x8e41ade9fbebc27d, 0x14588f13be847307, + 0xb1d219647ae6b31c, 0x596eb2d8ae258fc8, + 0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bb, + 0x8aec23d680043bee, 0x25de7bb9480d5854, + 0xada72ccc20054ae9, 0xaf561aa79a10ae6a, + 0xd910f7ff28069da4, 0x1b2ba1518094da04, + 0x87aa9aff79042286, 0x90fb44d2f05d0842, + 0xa99541bf57452b28, 0x353a1607ac744a53, + 0xd3fa922f2d1675f2, 0x42889b8997915ce8, + 0x847c9b5d7c2e09b7, 0x69956135febada11, + 0xa59bc234db398c25, 0x43fab9837e699095, + 0xcf02b2c21207ef2e, 0x94f967e45e03f4bb, + 0x8161afb94b44f57d, 0x1d1be0eebac278f5, + 0xa1ba1ba79e1632dc, 0x6462d92a69731732, + 0xca28a291859bbf93, 0x7d7b8f7503cfdcfe, + 0xfcb2cb35e702af78, 0x5cda735244c3d43e, + 0x9defbf01b061adab, 0x3a0888136afa64a7, + 0xc56baec21c7a1916, 0x88aaa1845b8fdd0, + 0xf6c69a72a3989f5b, 0x8aad549e57273d45, + 0x9a3c2087a63f6399, 0x36ac54e2f678864b, + 0xc0cb28a98fcf3c7f, 0x84576a1bb416a7dd, + 0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d5, + 0x969eb7c47859e743, 0x9f644ae5a4b1b325, + 0xbc4665b596706114, 0x873d5d9f0dde1fee, + 0xeb57ff22fc0c7959, 0xa90cb506d155a7ea, + 0x9316ff75dd87cbd8, 0x9a7f12442d588f2, + 0xb7dcbf5354e9bece, 0xc11ed6d538aeb2f, + 0xe5d3ef282a242e81, 0x8f1668c8a86da5fa, + 0x8fa475791a569d10, 0xf96e017d694487bc, + 0xb38d92d760ec4455, 0x37c981dcc395a9ac, + 0xe070f78d3927556a, 0x85bbe253f47b1417, + 0x8c469ab843b89562, 0x93956d7478ccec8e, + 0xaf58416654a6babb, 0x387ac8d1970027b2, + 0xdb2e51bfe9d0696a, 0x6997b05fcc0319e, + 0x88fcf317f22241e2, 0x441fece3bdf81f03, + 0xab3c2fddeeaad25a, 0xd527e81cad7626c3, + 0xd60b3bd56a5586f1, 0x8a71e223d8d3b074, + 0x85c7056562757456, 0xf6872d5667844e49, + 0xa738c6bebb12d16c, 0xb428f8ac016561db, + 0xd106f86e69d785c7, 0xe13336d701beba52, + 0x82a45b450226b39c, 0xecc0024661173473, + 0xa34d721642b06084, 0x27f002d7f95d0190, + 0xcc20ce9bd35c78a5, 0x31ec038df7b441f4, + 0xff290242c83396ce, 0x7e67047175a15271, + 0x9f79a169bd203e41, 0xf0062c6e984d386, + 0xc75809c42c684dd1, 0x52c07b78a3e60868, + 0xf92e0c3537826145, 0xa7709a56ccdf8a82, + 0x9bbcc7a142b17ccb, 0x88a66076400bb691, + 0xc2abf989935ddbfe, 0x6acff893d00ea435, + 0xf356f7ebf83552fe, 0x583f6b8c4124d43, + 0x98165af37b2153de, 0xc3727a337a8b704a, + 0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5c, + 0xeda2ee1c7064130c, 0x1162def06f79df73, + 0x9485d4d1c63e8be7, 0x8addcb5645ac2ba8, + 0xb9a74a0637ce2ee1, 0x6d953e2bd7173692, + 0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0437, + 0x910ab1d4db9914a0, 0x1d9c9892400a22a2, + 0xb54d5e4a127f59c8, 0x2503beb6d00cab4b, + 0xe2a0b5dc971f303a, 0x2e44ae64840fd61d, + 0x8da471a9de737e24, 0x5ceaecfed289e5d2, + 0xb10d8e1456105dad, 0x7425a83e872c5f47, + 0xdd50f1996b947518, 0xd12f124e28f77719, + 0x8a5296ffe33cc92f, 0x82bd6b70d99aaa6f, + 0xace73cbfdc0bfb7b, 0x636cc64d1001550b, + 0xd8210befd30efa5a, 0x3c47f7e05401aa4e, + 0x8714a775e3e95c78, 0x65acfaec34810a71, + 0xa8d9d1535ce3b396, 0x7f1839a741a14d0d, + 0xd31045a8341ca07c, 0x1ede48111209a050, + 0x83ea2b892091e44d, 0x934aed0aab460432, + 0xa4e4b66b68b65d60, 0xf81da84d5617853f, + 0xce1de40642e3f4b9, 0x36251260ab9d668e, + 0x80d2ae83e9ce78f3, 0xc1d72b7c6b426019, + 0xa1075a24e4421730, 0xb24cf65b8612f81f, + 0xc94930ae1d529cfc, 0xdee033f26797b627, + 0xfb9b7cd9a4a7443c, 0x169840ef017da3b1, + 0x9d412e0806e88aa5, 0x8e1f289560ee864e, + 0xc491798a08a2ad4e, 0xf1a6f2bab92a27e2, + 0xf5b5d7ec8acb58a2, 0xae10af696774b1db, + 0x9991a6f3d6bf1765, 0xacca6da1e0a8ef29, + 0xbff610b0cc6edd3f, 0x17fd090a58d32af3, + 0xeff394dcff8a948e, 0xddfc4b4cef07f5b0, + 0x95f83d0a1fb69cd9, 0x4abdaf101564f98e, + 0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f1, + 0xea53df5fd18d5513, 0x84c86189216dc5ed, + 0x92746b9be2f8552c, 0x32fd3cf5b4e49bb4, + 0xb7118682dbb66a77, 0x3fbc8c33221dc2a1, + 0xe4d5e82392a40515, 0xfabaf3feaa5334a, + 0x8f05b1163ba6832d, 0x29cb4d87f2a7400e, + 0xb2c71d5bca9023f8, 0x743e20e9ef511012, + 0xdf78e4b2bd342cf6, 0x914da9246b255416, + 0x8bab8eefb6409c1a, 0x1ad089b6c2f7548e, + 0xae9672aba3d0c320, 0xa184ac2473b529b1, + 0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741e, + 0x8865899617fb1871, 0x7e2fa67c7a658892, + 0xaa7eebfb9df9de8d, 0xddbb901b98feeab7, + 0xd51ea6fa85785631, 0x552a74227f3ea565, + 0x8533285c936b35de, 0xd53a88958f87275f, + 0xa67ff273b8460356, 0x8a892abaf368f137, + 0xd01fef10a657842c, 0x2d2b7569b0432d85, + 0x8213f56a67f6b29b, 0x9c3b29620e29fc73, + 0xa298f2c501f45f42, 0x8349f3ba91b47b8f, + 0xcb3f2f7642717713, 0x241c70a936219a73, + 0xfe0efb53d30dd4d7, 0xed238cd383aa0110, + 0x9ec95d1463e8a506, 0xf4363804324a40aa, + 0xc67bb4597ce2ce48, 0xb143c6053edcd0d5, + 0xf81aa16fdc1b81da, 0xdd94b7868e94050a, + 0x9b10a4e5e9913128, 0xca7cf2b4191c8326, + 0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f0, + 0xf24a01a73cf2dccf, 0xbc633b39673c8cec, + 0x976e41088617ca01, 0xd5be0503e085d813, + 0xbd49d14aa79dbc82, 0x4b2d8644d8a74e18, + 0xec9c459d51852ba2, 0xddf8e7d60ed1219e, + 0x93e1ab8252f33b45, 0xcabb90e5c942b503, + 0xb8da1662e7b00a17, 0x3d6a751f3b936243, + 0xe7109bfba19c0c9d, 0xcc512670a783ad4, + 0x906a617d450187e2, 0x27fb2b80668b24c5, + 0xb484f9dc9641e9da, 0xb1f9f660802dedf6, + 0xe1a63853bbd26451, 0x5e7873f8a0396973, + 0x8d07e33455637eb2, 0xdb0b487b6423e1e8, + 0xb049dc016abc5e5f, 0x91ce1a9a3d2cda62, + 0xdc5c5301c56b75f7, 0x7641a140cc7810fb, + 0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9d, + 0xac2820d9623bf429, 0x546345fa9fbdcd44, + 0xd732290fbacaf133, 0xa97c177947ad4095, + 0x867f59a9d4bed6c0, 0x49ed8eabcccc485d, + 0xa81f301449ee8c70, 0x5c68f256bfff5a74, + 0xd226fc195c6a2f8c, 0x73832eec6fff3111, + 0x83585d8fd9c25db7, 0xc831fd53c5ff7eab, + 0xa42e74f3d032f525, 0xba3e7ca8b77f5e55, + 0xcd3a1230c43fb26f, 0x28ce1bd2e55f35eb, + 0x80444b5e7aa7cf85, 0x7980d163cf5b81b3, + 0xa0555e361951c366, 0xd7e105bcc332621f, + 0xc86ab5c39fa63440, 0x8dd9472bf3fefaa7, + 0xfa856334878fc150, 0xb14f98f6f0feb951, + 0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d3, + 0xc3b8358109e84f07, 0xa862f80ec4700c8, + 0xf4a642e14c6262c8, 0xcd27bb612758c0fa, + 0x98e7e9cccfbd7dbd, 0x8038d51cb897789c, + 0xbf21e44003acdd2c, 0xe0470a63e6bd56c3, + 0xeeea5d5004981478, 0x1858ccfce06cac74, + 0x95527a5202df0ccb, 0xf37801e0c43ebc8, + 0xbaa718e68396cffd, 0xd30560258f54e6ba, + 0xe950df20247c83fd, 0x47c6b82ef32a2069, + 0x91d28b7416cdd27e, 0x4cdc331d57fa5441, + 0xb6472e511c81471d, 0xe0133fe4adf8e952, + 0xe3d8f9e563a198e5, 0x58180fddd97723a6, + 0x8e679c2f5e44ff8f, 0x570f09eaa7ea7648, + }; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template +constexpr uint64_t + powers_template::power_of_five_128[number_of_entries]; + +#endif + +using powers = powers_template<>; + +} // namespace fast_float + +#endif + +#ifndef FASTFLOAT_DECIMAL_TO_BINARY_H +#define FASTFLOAT_DECIMAL_TO_BINARY_H + +#include +#include +#include +#include +#include +#include + +namespace fast_float { + +// This will compute or rather approximate w * 5**q and return a pair of 64-bit +// words approximating the result, with the "high" part corresponding to the +// most significant bits and the low part corresponding to the least significant +// bits. +// +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 value128 +compute_product_approximation(int64_t q, uint64_t w) { + const int index = 2 * int(q - powers::smallest_power_of_five); + // For small values of q, e.g., q in [0,27], the answer is always exact + // because The line value128 firstproduct = full_multiplication(w, + // power_of_five_128[index]); gives the exact answer. + value128 firstproduct = + full_multiplication(w, powers::power_of_five_128[index]); + static_assert((bit_precision >= 0) && (bit_precision <= 64), + " precision should be in (0,64]"); + constexpr uint64_t precision_mask = + (bit_precision < 64) ? (uint64_t(0xFFFFFFFFFFFFFFFF) >> bit_precision) + : uint64_t(0xFFFFFFFFFFFFFFFF); + if ((firstproduct.high & precision_mask) == + precision_mask) { // could further guard with (lower + w < lower) + // regarding the second product, we only need secondproduct.high, but our + // expectation is that the compiler will optimize this extra work away if + // needed. + value128 secondproduct = + full_multiplication(w, powers::power_of_five_128[index + 1]); + firstproduct.low += secondproduct.high; + if (secondproduct.high > firstproduct.low) { + firstproduct.high++; + } + } + return firstproduct; +} + +namespace detail { +/** + * For q in (0,350), we have that + * f = (((152170 + 65536) * q ) >> 16); + * is equal to + * floor(p) + q + * where + * p = log(5**q)/log(2) = q * log(5)/log(2) + * + * For negative values of q in (-400,0), we have that + * f = (((152170 + 65536) * q ) >> 16); + * is equal to + * -ceil(p) + q + * where + * p = log(5**-q)/log(2) = -q * log(5)/log(2) + */ +constexpr fastfloat_really_inline int32_t power(int32_t q) noexcept { + return (((152170 + 65536) * q) >> 16) + 63; +} +} // namespace detail + +// create an adjusted mantissa, biased by the invalid power2 +// for significant digits already multiplied by 10 ** q. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 adjusted_mantissa +compute_error_scaled(int64_t q, uint64_t w, int lz) noexcept { + int hilz = int(w >> 63) ^ 1; + adjusted_mantissa answer; + answer.mantissa = w << hilz; + int bias = binary::mantissa_explicit_bits() - binary::minimum_exponent(); + answer.power2 = int32_t(detail::power(int32_t(q)) + bias - hilz - lz - 62 + + invalid_am_bias); + return answer; +} + +// w * 10 ** q, without rounding the representation up. +// the power2 in the exponent will be adjusted by invalid_am_bias. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +compute_error(int64_t q, uint64_t w) noexcept { + int lz = leading_zeroes(w); + w <<= lz; + value128 product = + compute_product_approximation(q, w); + return compute_error_scaled(q, product.high, lz); +} + +// w * 10 ** q +// The returned value should be a valid ieee64 number that simply need to be +// packed. However, in some very rare cases, the computation will fail. In such +// cases, we return an adjusted_mantissa with a negative power of 2: the caller +// should recompute in such cases. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +compute_float(int64_t q, uint64_t w) noexcept { + adjusted_mantissa answer; + if ((w == 0) || (q < binary::smallest_power_of_ten())) { + answer.power2 = 0; + answer.mantissa = 0; + // result should be zero + return answer; + } + if (q > binary::largest_power_of_ten()) { + // we want to get infinity: + answer.power2 = binary::infinite_power(); + answer.mantissa = 0; + return answer; + } + // At this point in time q is in [powers::smallest_power_of_five, + // powers::largest_power_of_five]. + + // We want the most significant bit of i to be 1. Shift if needed. + int lz = leading_zeroes(w); + w <<= lz; + + // The required precision is binary::mantissa_explicit_bits() + 3 because + // 1. We need the implicit bit + // 2. We need an extra bit for rounding purposes + // 3. We might lose a bit due to the "upperbit" routine (result too small, + // requiring a shift) + + value128 product = + compute_product_approximation(q, w); + // The computed 'product' is always sufficient. + // Mathematical proof: + // Noble Mushtak and Daniel Lemire, Fast Number Parsing Without Fallback (to + // appear) See script/mushtak_lemire.py + + // The "compute_product_approximation" function can be slightly slower than a + // branchless approach: value128 product = compute_product(q, w); but in + // practice, we can win big with the compute_product_approximation if its + // additional branch is easily predicted. Which is best is data specific. + int upperbit = int(product.high >> 63); + int shift = upperbit + 64 - binary::mantissa_explicit_bits() - 3; + + answer.mantissa = product.high >> shift; + + answer.power2 = int32_t(detail::power(int32_t(q)) + upperbit - lz - + binary::minimum_exponent()); + if (answer.power2 <= 0) { // we have a subnormal? + // Here have that answer.power2 <= 0 so -answer.power2 >= 0 + if (-answer.power2 + 1 >= + 64) { // if we have more than 64 bits below the minimum exponent, you + // have a zero for sure. + answer.power2 = 0; + answer.mantissa = 0; + // result should be zero + return answer; + } + // next line is safe because -answer.power2 + 1 < 64 + answer.mantissa >>= -answer.power2 + 1; + // Thankfully, we can't have both "round-to-even" and subnormals because + // "round-to-even" only occurs for powers close to 0. + answer.mantissa += (answer.mantissa & 1); // round up + answer.mantissa >>= 1; + // There is a weird scenario where we don't have a subnormal but just. + // Suppose we start with 2.2250738585072013e-308, we end up + // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal + // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round + // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer + // subnormal, but we can only know this after rounding. + // So we only declare a subnormal if we are smaller than the threshold. + answer.power2 = + (answer.mantissa < (uint64_t(1) << binary::mantissa_explicit_bits())) + ? 0 + : 1; + return answer; + } + + // usually, we round *up*, but if we fall right in between and and we have an + // even basis, we need to round down + // We are only concerned with the cases where 5**q fits in single 64-bit word. + if ((product.low <= 1) && (q >= binary::min_exponent_round_to_even()) && + (q <= binary::max_exponent_round_to_even()) && + ((answer.mantissa & 3) == 1)) { // we may fall between two floats! + // To be in-between two floats we need that in doing + // answer.mantissa = product.high >> (upperbit + 64 - + // binary::mantissa_explicit_bits() - 3); + // ... we dropped out only zeroes. But if this happened, then we can go + // back!!! + if ((answer.mantissa << shift) == product.high) { + answer.mantissa &= ~uint64_t(1); // flip it so that we do not round up + } + } + + answer.mantissa += (answer.mantissa & 1); // round up + answer.mantissa >>= 1; + if (answer.mantissa >= (uint64_t(2) << binary::mantissa_explicit_bits())) { + answer.mantissa = (uint64_t(1) << binary::mantissa_explicit_bits()); + answer.power2++; // undo previous addition + } + + answer.mantissa &= ~(uint64_t(1) << binary::mantissa_explicit_bits()); + if (answer.power2 >= binary::infinite_power()) { // infinity + answer.power2 = binary::infinite_power(); + answer.mantissa = 0; + } + return answer; +} + +} // namespace fast_float + +#endif + +#ifndef FASTFLOAT_BIGINT_H +#define FASTFLOAT_BIGINT_H + +#include +#include +#include +#include + + +namespace fast_float { + +// the limb width: we want efficient multiplication of double the bits in +// limb, or for 64-bit limbs, at least 64-bit multiplication where we can +// extract the high and low parts efficiently. this is every 64-bit +// architecture except for sparc, which emulates 128-bit multiplication. +// we might have platforms where `CHAR_BIT` is not 8, so let's avoid +// doing `8 * sizeof(limb)`. +#if defined(FASTFLOAT_64BIT) && !defined(__sparc) +#define FASTFLOAT_64BIT_LIMB 1 +typedef uint64_t limb; +constexpr size_t limb_bits = 64; +#else +#define FASTFLOAT_32BIT_LIMB +typedef uint32_t limb; +constexpr size_t limb_bits = 32; +#endif + +typedef span limb_span; + +// number of bits in a bigint. this needs to be at least the number +// of bits required to store the largest bigint, which is +// `log2(10**(digits + max_exp))`, or `log2(10**(767 + 342))`, or +// ~3600 bits, so we round to 4000. +constexpr size_t bigint_bits = 4000; +constexpr size_t bigint_limbs = bigint_bits / limb_bits; + +// vector-like type that is allocated on the stack. the entire +// buffer is pre-allocated, and only the length changes. +template struct stackvec { + limb data[size]; + // we never need more than 150 limbs + uint16_t length{0}; + + stackvec() = default; + stackvec(const stackvec &) = delete; + stackvec &operator=(const stackvec &) = delete; + stackvec(stackvec &&) = delete; + stackvec &operator=(stackvec &&other) = delete; + + // create stack vector from existing limb span. + FASTFLOAT_CONSTEXPR20 stackvec(limb_span s) { + FASTFLOAT_ASSERT(try_extend(s)); + } + + FASTFLOAT_CONSTEXPR14 limb &operator[](size_t index) noexcept { + FASTFLOAT_DEBUG_ASSERT(index < length); + return data[index]; + } + FASTFLOAT_CONSTEXPR14 const limb &operator[](size_t index) const noexcept { + FASTFLOAT_DEBUG_ASSERT(index < length); + return data[index]; + } + // index from the end of the container + FASTFLOAT_CONSTEXPR14 const limb &rindex(size_t index) const noexcept { + FASTFLOAT_DEBUG_ASSERT(index < length); + size_t rindex = length - index - 1; + return data[rindex]; + } + + // set the length, without bounds checking. + FASTFLOAT_CONSTEXPR14 void set_len(size_t len) noexcept { + length = uint16_t(len); + } + constexpr size_t len() const noexcept { return length; } + constexpr bool is_empty() const noexcept { return length == 0; } + constexpr size_t capacity() const noexcept { return size; } + // append item to vector, without bounds checking + FASTFLOAT_CONSTEXPR14 void push_unchecked(limb value) noexcept { + data[length] = value; + length++; + } + // append item to vector, returning if item was added + FASTFLOAT_CONSTEXPR14 bool try_push(limb value) noexcept { + if (len() < capacity()) { + push_unchecked(value); + return true; + } else { + return false; + } + } + // add items to the vector, from a span, without bounds checking + FASTFLOAT_CONSTEXPR20 void extend_unchecked(limb_span s) noexcept { + limb *ptr = data + length; + std::copy_n(s.ptr, s.len(), ptr); + set_len(len() + s.len()); + } + // try to add items to the vector, returning if items were added + FASTFLOAT_CONSTEXPR20 bool try_extend(limb_span s) noexcept { + if (len() + s.len() <= capacity()) { + extend_unchecked(s); + return true; + } else { + return false; + } + } + // resize the vector, without bounds checking + // if the new size is longer than the vector, assign value to each + // appended item. + FASTFLOAT_CONSTEXPR20 + void resize_unchecked(size_t new_len, limb value) noexcept { + if (new_len > len()) { + size_t count = new_len - len(); + limb *first = data + len(); + limb *last = first + count; + ::std::fill(first, last, value); + set_len(new_len); + } else { + set_len(new_len); + } + } + // try to resize the vector, returning if the vector was resized. + FASTFLOAT_CONSTEXPR20 bool try_resize(size_t new_len, limb value) noexcept { + if (new_len > capacity()) { + return false; + } else { + resize_unchecked(new_len, value); + return true; + } + } + // check if any limbs are non-zero after the given index. + // this needs to be done in reverse order, since the index + // is relative to the most significant limbs. + FASTFLOAT_CONSTEXPR14 bool nonzero(size_t index) const noexcept { + while (index < len()) { + if (rindex(index) != 0) { + return true; + } + index++; + } + return false; + } + // normalize the big integer, so most-significant zero limbs are removed. + FASTFLOAT_CONSTEXPR14 void normalize() noexcept { + while (len() > 0 && rindex(0) == 0) { + length--; + } + } +}; + +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint64_t +empty_hi64(bool &truncated) noexcept { + truncated = false; + return 0; +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +uint64_hi64(uint64_t r0, bool &truncated) noexcept { + truncated = false; + int shl = leading_zeroes(r0); + return r0 << shl; +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +uint64_hi64(uint64_t r0, uint64_t r1, bool &truncated) noexcept { + int shl = leading_zeroes(r0); + if (shl == 0) { + truncated = r1 != 0; + return r0; + } else { + int shr = 64 - shl; + truncated = (r1 << shl) != 0; + return (r0 << shl) | (r1 >> shr); + } +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +uint32_hi64(uint32_t r0, bool &truncated) noexcept { + return uint64_hi64(r0, truncated); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +uint32_hi64(uint32_t r0, uint32_t r1, bool &truncated) noexcept { + uint64_t x0 = r0; + uint64_t x1 = r1; + return uint64_hi64((x0 << 32) | x1, truncated); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +uint32_hi64(uint32_t r0, uint32_t r1, uint32_t r2, bool &truncated) noexcept { + uint64_t x0 = r0; + uint64_t x1 = r1; + uint64_t x2 = r2; + return uint64_hi64(x0, (x1 << 32) | x2, truncated); +} + +// add two small integers, checking for overflow. +// we want an efficient operation. for msvc, where +// we don't have built-in intrinsics, this is still +// pretty fast. +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 limb +scalar_add(limb x, limb y, bool &overflow) noexcept { + limb z; +// gcc and clang +#if defined(__has_builtin) +#if __has_builtin(__builtin_add_overflow) + if (!cpp20_and_in_constexpr()) { + overflow = __builtin_add_overflow(x, y, &z); + return z; + } +#endif +#endif + + // generic, this still optimizes correctly on MSVC. + z = x + y; + overflow = z < x; + return z; +} + +// multiply two small integers, getting both the high and low bits. +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 limb +scalar_mul(limb x, limb y, limb &carry) noexcept { +#ifdef FASTFLOAT_64BIT_LIMB +#if defined(__SIZEOF_INT128__) + // GCC and clang both define it as an extension. + __uint128_t z = __uint128_t(x) * __uint128_t(y) + __uint128_t(carry); + carry = limb(z >> limb_bits); + return limb(z); +#else + // fallback, no native 128-bit integer multiplication with carry. + // on msvc, this optimizes identically, somehow. + value128 z = full_multiplication(x, y); + bool overflow; + z.low = scalar_add(z.low, carry, overflow); + z.high += uint64_t(overflow); // cannot overflow + carry = z.high; + return z.low; +#endif +#else + uint64_t z = uint64_t(x) * uint64_t(y) + uint64_t(carry); + carry = limb(z >> limb_bits); + return limb(z); +#endif +} + +// add scalar value to bigint starting from offset. +// used in grade school multiplication +template +inline FASTFLOAT_CONSTEXPR20 bool small_add_from(stackvec &vec, limb y, + size_t start) noexcept { + size_t index = start; + limb carry = y; + bool overflow; + while (carry != 0 && index < vec.len()) { + vec[index] = scalar_add(vec[index], carry, overflow); + carry = limb(overflow); + index += 1; + } + if (carry != 0) { + FASTFLOAT_TRY(vec.try_push(carry)); + } + return true; +} + +// add scalar value to bigint. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool +small_add(stackvec &vec, limb y) noexcept { + return small_add_from(vec, y, 0); +} + +// multiply bigint by scalar value. +template +inline FASTFLOAT_CONSTEXPR20 bool small_mul(stackvec &vec, + limb y) noexcept { + limb carry = 0; + for (size_t index = 0; index < vec.len(); index++) { + vec[index] = scalar_mul(vec[index], y, carry); + } + if (carry != 0) { + FASTFLOAT_TRY(vec.try_push(carry)); + } + return true; +} + +// add bigint to bigint starting from index. +// used in grade school multiplication +template +FASTFLOAT_CONSTEXPR20 bool large_add_from(stackvec &x, limb_span y, + size_t start) noexcept { + // the effective x buffer is from `xstart..x.len()`, so exit early + // if we can't get that current range. + if (x.len() < start || y.len() > x.len() - start) { + FASTFLOAT_TRY(x.try_resize(y.len() + start, 0)); + } + + bool carry = false; + for (size_t index = 0; index < y.len(); index++) { + limb xi = x[index + start]; + limb yi = y[index]; + bool c1 = false; + bool c2 = false; + xi = scalar_add(xi, yi, c1); + if (carry) { + xi = scalar_add(xi, 1, c2); + } + x[index + start] = xi; + carry = c1 | c2; + } + + // handle overflow + if (carry) { + FASTFLOAT_TRY(small_add_from(x, 1, y.len() + start)); + } + return true; +} + +// add bigint to bigint. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool +large_add_from(stackvec &x, limb_span y) noexcept { + return large_add_from(x, y, 0); +} + +// grade-school multiplication algorithm +template +FASTFLOAT_CONSTEXPR20 bool long_mul(stackvec &x, limb_span y) noexcept { + limb_span xs = limb_span(x.data, x.len()); + stackvec z(xs); + limb_span zs = limb_span(z.data, z.len()); + + if (y.len() != 0) { + limb y0 = y[0]; + FASTFLOAT_TRY(small_mul(x, y0)); + for (size_t index = 1; index < y.len(); index++) { + limb yi = y[index]; + stackvec zi; + if (yi != 0) { + // re-use the same buffer throughout + zi.set_len(0); + FASTFLOAT_TRY(zi.try_extend(zs)); + FASTFLOAT_TRY(small_mul(zi, yi)); + limb_span zis = limb_span(zi.data, zi.len()); + FASTFLOAT_TRY(large_add_from(x, zis, index)); + } + } + } + + x.normalize(); + return true; +} + +// grade-school multiplication algorithm +template +FASTFLOAT_CONSTEXPR20 bool large_mul(stackvec &x, limb_span y) noexcept { + if (y.len() == 1) { + FASTFLOAT_TRY(small_mul(x, y[0])); + } else { + FASTFLOAT_TRY(long_mul(x, y)); + } + return true; +} + +template struct pow5_tables { + static constexpr uint32_t large_step = 135; + static constexpr uint64_t small_power_of_5[] = { + 1UL, + 5UL, + 25UL, + 125UL, + 625UL, + 3125UL, + 15625UL, + 78125UL, + 390625UL, + 1953125UL, + 9765625UL, + 48828125UL, + 244140625UL, + 1220703125UL, + 6103515625UL, + 30517578125UL, + 152587890625UL, + 762939453125UL, + 3814697265625UL, + 19073486328125UL, + 95367431640625UL, + 476837158203125UL, + 2384185791015625UL, + 11920928955078125UL, + 59604644775390625UL, + 298023223876953125UL, + 1490116119384765625UL, + 7450580596923828125UL, + }; +#ifdef FASTFLOAT_64BIT_LIMB + constexpr static limb large_power_of_5[] = { + 1414648277510068013UL, 9180637584431281687UL, 4539964771860779200UL, + 10482974169319127550UL, 198276706040285095UL}; +#else + constexpr static limb large_power_of_5[] = { + 4279965485U, 329373468U, 4020270615U, 2137533757U, 4287402176U, + 1057042919U, 1071430142U, 2440757623U, 381945767U, 46164893U}; +#endif +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template constexpr uint32_t pow5_tables::large_step; + +template constexpr uint64_t pow5_tables::small_power_of_5[]; + +template constexpr limb pow5_tables::large_power_of_5[]; + +#endif + +// big integer type. implements a small subset of big integer +// arithmetic, using simple algorithms since asymptotically +// faster algorithms are slower for a small number of limbs. +// all operations assume the big-integer is normalized. +struct bigint : pow5_tables<> { + // storage of the limbs, in little-endian order. + stackvec vec; + + FASTFLOAT_CONSTEXPR20 bigint() : vec() {} + bigint(const bigint &) = delete; + bigint &operator=(const bigint &) = delete; + bigint(bigint &&) = delete; + bigint &operator=(bigint &&other) = delete; + + FASTFLOAT_CONSTEXPR20 bigint(uint64_t value) : vec() { +#ifdef FASTFLOAT_64BIT_LIMB + vec.push_unchecked(value); +#else + vec.push_unchecked(uint32_t(value)); + vec.push_unchecked(uint32_t(value >> 32)); +#endif + vec.normalize(); + } + + // get the high 64 bits from the vector, and if bits were truncated. + // this is to get the significant digits for the float. + FASTFLOAT_CONSTEXPR20 uint64_t hi64(bool &truncated) const noexcept { +#ifdef FASTFLOAT_64BIT_LIMB + if (vec.len() == 0) { + return empty_hi64(truncated); + } else if (vec.len() == 1) { + return uint64_hi64(vec.rindex(0), truncated); + } else { + uint64_t result = uint64_hi64(vec.rindex(0), vec.rindex(1), truncated); + truncated |= vec.nonzero(2); + return result; + } +#else + if (vec.len() == 0) { + return empty_hi64(truncated); + } else if (vec.len() == 1) { + return uint32_hi64(vec.rindex(0), truncated); + } else if (vec.len() == 2) { + return uint32_hi64(vec.rindex(0), vec.rindex(1), truncated); + } else { + uint64_t result = + uint32_hi64(vec.rindex(0), vec.rindex(1), vec.rindex(2), truncated); + truncated |= vec.nonzero(3); + return result; + } +#endif + } + + // compare two big integers, returning the large value. + // assumes both are normalized. if the return value is + // negative, other is larger, if the return value is + // positive, this is larger, otherwise they are equal. + // the limbs are stored in little-endian order, so we + // must compare the limbs in ever order. + FASTFLOAT_CONSTEXPR20 int compare(const bigint &other) const noexcept { + if (vec.len() > other.vec.len()) { + return 1; + } else if (vec.len() < other.vec.len()) { + return -1; + } else { + for (size_t index = vec.len(); index > 0; index--) { + limb xi = vec[index - 1]; + limb yi = other.vec[index - 1]; + if (xi > yi) { + return 1; + } else if (xi < yi) { + return -1; + } + } + return 0; + } + } + + // shift left each limb n bits, carrying over to the new limb + // returns true if we were able to shift all the digits. + FASTFLOAT_CONSTEXPR20 bool shl_bits(size_t n) noexcept { + // Internally, for each item, we shift left by n, and add the previous + // right shifted limb-bits. + // For example, we transform (for u8) shifted left 2, to: + // b10100100 b01000010 + // b10 b10010001 b00001000 + FASTFLOAT_DEBUG_ASSERT(n != 0); + FASTFLOAT_DEBUG_ASSERT(n < sizeof(limb) * 8); + + size_t shl = n; + size_t shr = limb_bits - shl; + limb prev = 0; + for (size_t index = 0; index < vec.len(); index++) { + limb xi = vec[index]; + vec[index] = (xi << shl) | (prev >> shr); + prev = xi; + } + + limb carry = prev >> shr; + if (carry != 0) { + return vec.try_push(carry); + } + return true; + } + + // move the limbs left by `n` limbs. + FASTFLOAT_CONSTEXPR20 bool shl_limbs(size_t n) noexcept { + FASTFLOAT_DEBUG_ASSERT(n != 0); + if (n + vec.len() > vec.capacity()) { + return false; + } else if (!vec.is_empty()) { + // move limbs + limb *dst = vec.data + n; + const limb *src = vec.data; + std::copy_backward(src, src + vec.len(), dst + vec.len()); + // fill in empty limbs + limb *first = vec.data; + limb *last = first + n; + ::std::fill(first, last, 0); + vec.set_len(n + vec.len()); + return true; + } else { + return true; + } + } + + // move the limbs left by `n` bits. + FASTFLOAT_CONSTEXPR20 bool shl(size_t n) noexcept { + size_t rem = n % limb_bits; + size_t div = n / limb_bits; + if (rem != 0) { + FASTFLOAT_TRY(shl_bits(rem)); + } + if (div != 0) { + FASTFLOAT_TRY(shl_limbs(div)); + } + return true; + } + + // get the number of leading zeros in the bigint. + FASTFLOAT_CONSTEXPR20 int ctlz() const noexcept { + if (vec.is_empty()) { + return 0; + } else { +#ifdef FASTFLOAT_64BIT_LIMB + return leading_zeroes(vec.rindex(0)); +#else + // no use defining a specialized leading_zeroes for a 32-bit type. + uint64_t r0 = vec.rindex(0); + return leading_zeroes(r0 << 32); +#endif + } + } + + // get the number of bits in the bigint. + FASTFLOAT_CONSTEXPR20 int bit_length() const noexcept { + int lz = ctlz(); + return int(limb_bits * vec.len()) - lz; + } + + FASTFLOAT_CONSTEXPR20 bool mul(limb y) noexcept { return small_mul(vec, y); } + + FASTFLOAT_CONSTEXPR20 bool add(limb y) noexcept { return small_add(vec, y); } + + // multiply as if by 2 raised to a power. + FASTFLOAT_CONSTEXPR20 bool pow2(uint32_t exp) noexcept { return shl(exp); } + + // multiply as if by 5 raised to a power. + FASTFLOAT_CONSTEXPR20 bool pow5(uint32_t exp) noexcept { + // multiply by a power of 5 + size_t large_length = sizeof(large_power_of_5) / sizeof(limb); + limb_span large = limb_span(large_power_of_5, large_length); + while (exp >= large_step) { + FASTFLOAT_TRY(large_mul(vec, large)); + exp -= large_step; + } +#ifdef FASTFLOAT_64BIT_LIMB + uint32_t small_step = 27; + limb max_native = 7450580596923828125UL; +#else + uint32_t small_step = 13; + limb max_native = 1220703125U; +#endif + while (exp >= small_step) { + FASTFLOAT_TRY(small_mul(vec, max_native)); + exp -= small_step; + } + if (exp != 0) { + // Work around clang bug https://godbolt.org/z/zedh7rrhc + // This is similar to https://github.com/llvm/llvm-project/issues/47746, + // except the workaround described there don't work here + FASTFLOAT_TRY(small_mul( + vec, limb(((void)small_power_of_5[0], small_power_of_5[exp])))); + } + + return true; + } + + // multiply as if by 10 raised to a power. + FASTFLOAT_CONSTEXPR20 bool pow10(uint32_t exp) noexcept { + FASTFLOAT_TRY(pow5(exp)); + return pow2(exp); + } +}; + +} // namespace fast_float + +#endif + +#ifndef FASTFLOAT_DIGIT_COMPARISON_H +#define FASTFLOAT_DIGIT_COMPARISON_H + +#include +#include +#include +#include + + +namespace fast_float { + +// 1e0 to 1e19 +constexpr static uint64_t powers_of_ten_uint64[] = {1UL, + 10UL, + 100UL, + 1000UL, + 10000UL, + 100000UL, + 1000000UL, + 10000000UL, + 100000000UL, + 1000000000UL, + 10000000000UL, + 100000000000UL, + 1000000000000UL, + 10000000000000UL, + 100000000000000UL, + 1000000000000000UL, + 10000000000000000UL, + 100000000000000000UL, + 1000000000000000000UL, + 10000000000000000000UL}; + +// calculate the exponent, in scientific notation, of the number. +// this algorithm is not even close to optimized, but it has no practical +// effect on performance: in order to have a faster algorithm, we'd need +// to slow down performance for faster algorithms, and this is still fast. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 int32_t +scientific_exponent(parsed_number_string_t &num) noexcept { + uint64_t mantissa = num.mantissa; + int32_t exponent = int32_t(num.exponent); + while (mantissa >= 10000) { + mantissa /= 10000; + exponent += 4; + } + while (mantissa >= 100) { + mantissa /= 100; + exponent += 2; + } + while (mantissa >= 10) { + mantissa /= 10; + exponent += 1; + } + return exponent; +} + +// this converts a native floating-point number to an extended-precision float. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +to_extended(T value) noexcept { + using equiv_uint = typename binary_format::equiv_uint; + constexpr equiv_uint exponent_mask = binary_format::exponent_mask(); + constexpr equiv_uint mantissa_mask = binary_format::mantissa_mask(); + constexpr equiv_uint hidden_bit_mask = binary_format::hidden_bit_mask(); + + adjusted_mantissa am; + int32_t bias = binary_format::mantissa_explicit_bits() - + binary_format::minimum_exponent(); + equiv_uint bits; +#if FASTFLOAT_HAS_BIT_CAST + bits = std::bit_cast(value); +#else + ::memcpy(&bits, &value, sizeof(T)); +#endif + if ((bits & exponent_mask) == 0) { + // denormal + am.power2 = 1 - bias; + am.mantissa = bits & mantissa_mask; + } else { + // normal + am.power2 = int32_t((bits & exponent_mask) >> + binary_format::mantissa_explicit_bits()); + am.power2 -= bias; + am.mantissa = (bits & mantissa_mask) | hidden_bit_mask; + } + + return am; +} + +// get the extended precision value of the halfway point between b and b+u. +// we are given a native float that represents b, so we need to adjust it +// halfway between b and b+u. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +to_extended_halfway(T value) noexcept { + adjusted_mantissa am = to_extended(value); + am.mantissa <<= 1; + am.mantissa += 1; + am.power2 -= 1; + return am; +} + +// round an extended-precision float to the nearest machine float. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void round(adjusted_mantissa &am, + callback cb) noexcept { + int32_t mantissa_shift = 64 - binary_format::mantissa_explicit_bits() - 1; + if (-am.power2 >= mantissa_shift) { + // have a denormal float + int32_t shift = -am.power2 + 1; + cb(am, std::min(shift, 64)); + // check for round-up: if rounding-nearest carried us to the hidden bit. + am.power2 = (am.mantissa < + (uint64_t(1) << binary_format::mantissa_explicit_bits())) + ? 0 + : 1; + return; + } + + // have a normal float, use the default shift. + cb(am, mantissa_shift); + + // check for carry + if (am.mantissa >= + (uint64_t(2) << binary_format::mantissa_explicit_bits())) { + am.mantissa = (uint64_t(1) << binary_format::mantissa_explicit_bits()); + am.power2++; + } + + // check for infinite: we could have carried to an infinite power + am.mantissa &= ~(uint64_t(1) << binary_format::mantissa_explicit_bits()); + if (am.power2 >= binary_format::infinite_power()) { + am.power2 = binary_format::infinite_power(); + am.mantissa = 0; + } +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void +round_nearest_tie_even(adjusted_mantissa &am, int32_t shift, + callback cb) noexcept { + const uint64_t mask = (shift == 64) ? UINT64_MAX : (uint64_t(1) << shift) - 1; + const uint64_t halfway = (shift == 0) ? 0 : uint64_t(1) << (shift - 1); + uint64_t truncated_bits = am.mantissa & mask; + bool is_above = truncated_bits > halfway; + bool is_halfway = truncated_bits == halfway; + + // shift digits into position + if (shift == 64) { + am.mantissa = 0; + } else { + am.mantissa >>= shift; + } + am.power2 += shift; + + bool is_odd = (am.mantissa & 1) == 1; + am.mantissa += uint64_t(cb(is_odd, is_halfway, is_above)); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void +round_down(adjusted_mantissa &am, int32_t shift) noexcept { + if (shift == 64) { + am.mantissa = 0; + } else { + am.mantissa >>= shift; + } + am.power2 += shift; +} +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +skip_zeros(UC const *&first, UC const *last) noexcept { + uint64_t val; + while (!cpp20_and_in_constexpr() && + std::distance(first, last) >= int_cmp_len()) { + ::memcpy(&val, first, sizeof(uint64_t)); + if (val != int_cmp_zeros()) { + break; + } + first += int_cmp_len(); + } + while (first != last) { + if (*first != UC('0')) { + break; + } + first++; + } +} + +// determine if any non-zero digits were truncated. +// all characters must be valid digits. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool +is_truncated(UC const *first, UC const *last) noexcept { + // do 8-bit optimizations, can just compare to 8 literal 0s. + uint64_t val; + while (!cpp20_and_in_constexpr() && + std::distance(first, last) >= int_cmp_len()) { + ::memcpy(&val, first, sizeof(uint64_t)); + if (val != int_cmp_zeros()) { + return true; + } + first += int_cmp_len(); + } + while (first != last) { + if (*first != UC('0')) { + return true; + } + ++first; + } + return false; +} +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool +is_truncated(span s) noexcept { + return is_truncated(s.ptr, s.ptr + s.len()); +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +parse_eight_digits(const UC *&p, limb &value, size_t &counter, + size_t &count) noexcept { + value = value * 100000000 + parse_eight_digits_unrolled(p); + p += 8; + counter += 8; + count += 8; +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void +parse_one_digit(UC const *&p, limb &value, size_t &counter, + size_t &count) noexcept { + value = value * 10 + limb(*p - UC('0')); + p++; + counter++; + count++; +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +add_native(bigint &big, limb power, limb value) noexcept { + big.mul(power); + big.add(value); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +round_up_bigint(bigint &big, size_t &count) noexcept { + // need to round-up the digits, but need to avoid rounding + // ....9999 to ...10000, which could cause a false halfway point. + add_native(big, 10, 1); + count++; +} + +// parse the significant digits into a big integer +template +inline FASTFLOAT_CONSTEXPR20 void +parse_mantissa(bigint &result, parsed_number_string_t &num, + size_t max_digits, size_t &digits) noexcept { + // try to minimize the number of big integer and scalar multiplication. + // therefore, try to parse 8 digits at a time, and multiply by the largest + // scalar value (9 or 19 digits) for each step. + size_t counter = 0; + digits = 0; + limb value = 0; +#ifdef FASTFLOAT_64BIT_LIMB + size_t step = 19; +#else + size_t step = 9; +#endif + + // process all integer digits. + UC const *p = num.integer.ptr; + UC const *pend = p + num.integer.len(); + skip_zeros(p, pend); + // process all digits, in increments of step per loop + while (p != pend) { + while ((std::distance(p, pend) >= 8) && (step - counter >= 8) && + (max_digits - digits >= 8)) { + parse_eight_digits(p, value, counter, digits); + } + while (counter < step && p != pend && digits < max_digits) { + parse_one_digit(p, value, counter, digits); + } + if (digits == max_digits) { + // add the temporary value, then check if we've truncated any digits + add_native(result, limb(powers_of_ten_uint64[counter]), value); + bool truncated = is_truncated(p, pend); + if (num.fraction.ptr != nullptr) { + truncated |= is_truncated(num.fraction); + } + if (truncated) { + round_up_bigint(result, digits); + } + return; + } else { + add_native(result, limb(powers_of_ten_uint64[counter]), value); + counter = 0; + value = 0; + } + } + + // add our fraction digits, if they're available. + if (num.fraction.ptr != nullptr) { + p = num.fraction.ptr; + pend = p + num.fraction.len(); + if (digits == 0) { + skip_zeros(p, pend); + } + // process all digits, in increments of step per loop + while (p != pend) { + while ((std::distance(p, pend) >= 8) && (step - counter >= 8) && + (max_digits - digits >= 8)) { + parse_eight_digits(p, value, counter, digits); + } + while (counter < step && p != pend && digits < max_digits) { + parse_one_digit(p, value, counter, digits); + } + if (digits == max_digits) { + // add the temporary value, then check if we've truncated any digits + add_native(result, limb(powers_of_ten_uint64[counter]), value); + bool truncated = is_truncated(p, pend); + if (truncated) { + round_up_bigint(result, digits); + } + return; + } else { + add_native(result, limb(powers_of_ten_uint64[counter]), value); + counter = 0; + value = 0; + } + } + } + + if (counter != 0) { + add_native(result, limb(powers_of_ten_uint64[counter]), value); + } +} + +template +inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +positive_digit_comp(bigint &bigmant, int32_t exponent) noexcept { + FASTFLOAT_ASSERT(bigmant.pow10(uint32_t(exponent))); + adjusted_mantissa answer; + bool truncated; + answer.mantissa = bigmant.hi64(truncated); + int bias = binary_format::mantissa_explicit_bits() - + binary_format::minimum_exponent(); + answer.power2 = bigmant.bit_length() - 64 + bias; + + round(answer, [truncated](adjusted_mantissa &a, int32_t shift) { + round_nearest_tie_even( + a, shift, + [truncated](bool is_odd, bool is_halfway, bool is_above) -> bool { + return is_above || (is_halfway && truncated) || + (is_odd && is_halfway); + }); + }); + + return answer; +} + +// the scaling here is quite simple: we have, for the real digits `m * 10^e`, +// and for the theoretical digits `n * 2^f`. Since `e` is always negative, +// to scale them identically, we do `n * 2^f * 5^-f`, so we now have `m * 2^e`. +// we then need to scale by `2^(f- e)`, and then the two significant digits +// are of the same magnitude. +template +inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa negative_digit_comp( + bigint &bigmant, adjusted_mantissa am, int32_t exponent) noexcept { + bigint &real_digits = bigmant; + int32_t real_exp = exponent; + + // get the value of `b`, rounded down, and get a bigint representation of b+h + adjusted_mantissa am_b = am; + // gcc7 buf: use a lambda to remove the noexcept qualifier bug with + // -Wnoexcept-type. + round(am_b, + [](adjusted_mantissa &a, int32_t shift) { round_down(a, shift); }); + T b; + to_float(false, am_b, b); + adjusted_mantissa theor = to_extended_halfway(b); + bigint theor_digits(theor.mantissa); + int32_t theor_exp = theor.power2; + + // scale real digits and theor digits to be same power. + int32_t pow2_exp = theor_exp - real_exp; + uint32_t pow5_exp = uint32_t(-real_exp); + if (pow5_exp != 0) { + FASTFLOAT_ASSERT(theor_digits.pow5(pow5_exp)); + } + if (pow2_exp > 0) { + FASTFLOAT_ASSERT(theor_digits.pow2(uint32_t(pow2_exp))); + } else if (pow2_exp < 0) { + FASTFLOAT_ASSERT(real_digits.pow2(uint32_t(-pow2_exp))); + } + + // compare digits, and use it to director rounding + int ord = real_digits.compare(theor_digits); + adjusted_mantissa answer = am; + round(answer, [ord](adjusted_mantissa &a, int32_t shift) { + round_nearest_tie_even( + a, shift, [ord](bool is_odd, bool _, bool __) -> bool { + (void)_; // not needed, since we've done our comparison + (void)__; // not needed, since we've done our comparison + if (ord > 0) { + return true; + } else if (ord < 0) { + return false; + } else { + return is_odd; + } + }); + }); + + return answer; +} + +// parse the significant digits as a big integer to unambiguously round the +// the significant digits. here, we are trying to determine how to round +// an extended float representation close to `b+h`, halfway between `b` +// (the float rounded-down) and `b+u`, the next positive float. this +// algorithm is always correct, and uses one of two approaches. when +// the exponent is positive relative to the significant digits (such as +// 1234), we create a big-integer representation, get the high 64-bits, +// determine if any lower bits are truncated, and use that to direct +// rounding. in case of a negative exponent relative to the significant +// digits (such as 1.2345), we create a theoretical representation of +// `b` as a big-integer type, scaled to the same binary exponent as +// the actual digits. we then compare the big integer representations +// of both, and use that to direct rounding. +template +inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +digit_comp(parsed_number_string_t &num, adjusted_mantissa am) noexcept { + // remove the invalid exponent bias + am.power2 -= invalid_am_bias; + + int32_t sci_exp = scientific_exponent(num); + size_t max_digits = binary_format::max_digits(); + size_t digits = 0; + bigint bigmant; + parse_mantissa(bigmant, num, max_digits, digits); + // can't underflow, since digits is at most max_digits. + int32_t exponent = sci_exp + 1 - int32_t(digits); + if (exponent >= 0) { + return positive_digit_comp(bigmant, exponent); + } else { + return negative_digit_comp(bigmant, am, exponent); + } +} + +} // namespace fast_float + +#endif + +#ifndef FASTFLOAT_PARSE_NUMBER_H +#define FASTFLOAT_PARSE_NUMBER_H + + +#include +#include +#include +#include +namespace fast_float { + +namespace detail { +/** + * Special case +inf, -inf, nan, infinity, -infinity. + * The case comparisons could be made much faster given that we know that the + * strings a null-free and fixed. + **/ +template +from_chars_result_t FASTFLOAT_CONSTEXPR14 parse_infnan(UC const *first, + UC const *last, + T &value) noexcept { + from_chars_result_t answer{}; + answer.ptr = first; + answer.ec = std::errc(); // be optimistic + bool minusSign = false; + if (*first == + UC('-')) { // assume first < last, so dereference without checks; + // C++17 20.19.3.(7.1) explicitly forbids '+' here + minusSign = true; + ++first; + } +#ifdef FASTFLOAT_ALLOWS_LEADING_PLUS // disabled by default + if (*first == UC('+')) { + ++first; + } +#endif + if (last - first >= 3) { + if (fastfloat_strncasecmp(first, str_const_nan(), 3)) { + answer.ptr = (first += 3); + value = minusSign ? -std::numeric_limits::quiet_NaN() + : std::numeric_limits::quiet_NaN(); + // Check for possible nan(n-char-seq-opt), C++17 20.19.3.7, + // C11 7.20.1.3.3. At least MSVC produces nan(ind) and nan(snan). + if (first != last && *first == UC('(')) { + for (UC const *ptr = first + 1; ptr != last; ++ptr) { + if (*ptr == UC(')')) { + answer.ptr = ptr + 1; // valid nan(n-char-seq-opt) + break; + } else if (!((UC('a') <= *ptr && *ptr <= UC('z')) || + (UC('A') <= *ptr && *ptr <= UC('Z')) || + (UC('0') <= *ptr && *ptr <= UC('9')) || *ptr == UC('_'))) + break; // forbidden char, not nan(n-char-seq-opt) + } + } + return answer; + } + if (fastfloat_strncasecmp(first, str_const_inf(), 3)) { + if ((last - first >= 8) && + fastfloat_strncasecmp(first + 3, str_const_inf() + 3, 5)) { + answer.ptr = first + 8; + } else { + answer.ptr = first + 3; + } + value = minusSign ? -std::numeric_limits::infinity() + : std::numeric_limits::infinity(); + return answer; + } + } + answer.ec = std::errc::invalid_argument; + return answer; +} + +/** + * Returns true if the floating-pointing rounding mode is to 'nearest'. + * It is the default on most system. This function is meant to be inexpensive. + * Credit : @mwalcott3 + */ +fastfloat_really_inline bool rounds_to_nearest() noexcept { + // https://lemire.me/blog/2020/06/26/gcc-not-nearest/ +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + return false; +#endif + // See + // A fast function to check your floating-point rounding mode + // https://lemire.me/blog/2022/11/16/a-fast-function-to-check-your-floating-point-rounding-mode/ + // + // This function is meant to be equivalent to : + // prior: #include + // return fegetround() == FE_TONEAREST; + // However, it is expected to be much faster than the fegetround() + // function call. + // + // The volatile keywoard prevents the compiler from computing the function + // at compile-time. + // There might be other ways to prevent compile-time optimizations (e.g., + // asm). The value does not need to be std::numeric_limits::min(), any + // small value so that 1 + x should round to 1 would do (after accounting for + // excess precision, as in 387 instructions). + static volatile float fmin = std::numeric_limits::min(); + float fmini = fmin; // we copy it so that it gets loaded at most once. +// +// Explanation: +// Only when fegetround() == FE_TONEAREST do we have that +// fmin + 1.0f == 1.0f - fmin. +// +// FE_UPWARD: +// fmin + 1.0f > 1 +// 1.0f - fmin == 1 +// +// FE_DOWNWARD or FE_TOWARDZERO: +// fmin + 1.0f == 1 +// 1.0f - fmin < 1 +// +// Note: This may fail to be accurate if fast-math has been +// enabled, as rounding conventions may not apply. +#ifdef FASTFLOAT_VISUAL_STUDIO +#pragma warning(push) +// todo: is there a VS warning? +// see +// https://stackoverflow.com/questions/46079446/is-there-a-warning-for-floating-point-equality-checking-in-visual-studio-2013 +#elif defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wfloat-equal" +#elif defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + return (fmini + 1.0f == 1.0f - fmini); +#ifdef FASTFLOAT_VISUAL_STUDIO +#pragma warning(pop) +#elif defined(__clang__) +#pragma clang diagnostic pop +#elif defined(__GNUC__) +#pragma GCC diagnostic pop +#endif +} + +} // namespace detail + +template struct from_chars_caller { + template + FASTFLOAT_CONSTEXPR20 static from_chars_result_t + call(UC const *first, UC const *last, T &value, + parse_options_t options) noexcept { + return from_chars_advanced(first, last, value, options); + } +}; + +#if __STDCPP_FLOAT32_T__ == 1 +template <> struct from_chars_caller { + template + FASTFLOAT_CONSTEXPR20 static from_chars_result_t + call(UC const *first, UC const *last, std::float32_t &value, + parse_options_t options) noexcept { + // if std::float32_t is defined, and we are in C++23 mode; macro set for + // float32; set value to float due to equivalence between float and + // float32_t + float val; + auto ret = from_chars_advanced(first, last, val, options); + value = val; + return ret; + } +}; +#endif + +#if __STDCPP_FLOAT64_T__ == 1 +template <> struct from_chars_caller { + template + FASTFLOAT_CONSTEXPR20 static from_chars_result_t + call(UC const *first, UC const *last, std::float64_t &value, + parse_options_t options) noexcept { + // if std::float64_t is defined, and we are in C++23 mode; macro set for + // float64; set value as double due to equivalence between double and + // float64_t + double val; + auto ret = from_chars_advanced(first, last, val, options); + value = val; + return ret; + } +}; +#endif + +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars(UC const *first, UC const *last, T &value, + chars_format fmt /*= chars_format::general*/) noexcept { + return from_chars_caller::call(first, last, value, + parse_options_t(fmt)); +} + +/** + * This function overload takes parsed_number_string_t structure that is created + * and populated either by from_chars_advanced function taking chars range and + * parsing options or other parsing custom function implemented by user. + */ +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars_advanced(parsed_number_string_t &pns, T &value) noexcept { + + static_assert(is_supported_float_type(), + "only some floating-point types are supported"); + static_assert(is_supported_char_type(), + "only char, wchar_t, char16_t and char32_t are supported"); + + from_chars_result_t answer; + + answer.ec = std::errc(); // be optimistic + answer.ptr = pns.lastmatch; + // The implementation of the Clinger's fast path is convoluted because + // we want round-to-nearest in all cases, irrespective of the rounding mode + // selected on the thread. + // We proceed optimistically, assuming that detail::rounds_to_nearest() + // returns true. + if (binary_format::min_exponent_fast_path() <= pns.exponent && + pns.exponent <= binary_format::max_exponent_fast_path() && + !pns.too_many_digits) { + // Unfortunately, the conventional Clinger's fast path is only possible + // when the system rounds to the nearest float. + // + // We expect the next branch to almost always be selected. + // We could check it first (before the previous branch), but + // there might be performance advantages at having the check + // be last. + if (!cpp20_and_in_constexpr() && detail::rounds_to_nearest()) { + // We have that fegetround() == FE_TONEAREST. + // Next is Clinger's fast path. + if (pns.mantissa <= binary_format::max_mantissa_fast_path()) { + value = T(pns.mantissa); + if (pns.exponent < 0) { + value = value / binary_format::exact_power_of_ten(-pns.exponent); + } else { + value = value * binary_format::exact_power_of_ten(pns.exponent); + } + if (pns.negative) { + value = -value; + } + return answer; + } + } else { + // We do not have that fegetround() == FE_TONEAREST. + // Next is a modified Clinger's fast path, inspired by Jakub Jelínek's + // proposal + if (pns.exponent >= 0 && + pns.mantissa <= + binary_format::max_mantissa_fast_path(pns.exponent)) { +#if defined(__clang__) || defined(FASTFLOAT_32BIT) + // Clang may map 0 to -0.0 when fegetround() == FE_DOWNWARD + if (pns.mantissa == 0) { + value = pns.negative ? T(-0.) : T(0.); + return answer; + } +#endif + value = T(pns.mantissa) * + binary_format::exact_power_of_ten(pns.exponent); + if (pns.negative) { + value = -value; + } + return answer; + } + } + } + adjusted_mantissa am = + compute_float>(pns.exponent, pns.mantissa); + if (pns.too_many_digits && am.power2 >= 0) { + if (am != compute_float>(pns.exponent, pns.mantissa + 1)) { + am = compute_error>(pns.exponent, pns.mantissa); + } + } + // If we called compute_float>(pns.exponent, pns.mantissa) + // and we have an invalid power (am.power2 < 0), then we need to go the long + // way around again. This is very uncommon. + if (am.power2 < 0) { + am = digit_comp(pns, am); + } + to_float(pns.negative, am, value); + // Test for over/underflow. + if ((pns.mantissa != 0 && am.mantissa == 0 && am.power2 == 0) || + am.power2 == binary_format::infinite_power()) { + answer.ec = std::errc::result_out_of_range; + } + return answer; +} + +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars_advanced(UC const *first, UC const *last, T &value, + parse_options_t options) noexcept { + + static_assert(is_supported_float_type(), + "only some floating-point types are supported"); + static_assert(is_supported_char_type(), + "only char, wchar_t, char16_t and char32_t are supported"); + + from_chars_result_t answer; +#ifdef FASTFLOAT_SKIP_WHITE_SPACE // disabled by default + while ((first != last) && fast_float::is_space(uint8_t(*first))) { + first++; + } +#endif + if (first == last) { + answer.ec = std::errc::invalid_argument; + answer.ptr = first; + return answer; + } + parsed_number_string_t pns = + parse_number_string(first, last, options); + if (!pns.valid) { + if (options.format & chars_format::no_infnan) { + answer.ec = std::errc::invalid_argument; + answer.ptr = first; + return answer; + } else { + return detail::parse_infnan(first, last, value); + } + } + + // call overload that takes parsed_number_string_t directly. + return from_chars_advanced(pns, value); +} + +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars(UC const *first, UC const *last, T &value, int base) noexcept { + static_assert(is_supported_char_type(), + "only char, wchar_t, char16_t and char32_t are supported"); + + from_chars_result_t answer; +#ifdef FASTFLOAT_SKIP_WHITE_SPACE // disabled by default + while ((first != last) && fast_float::is_space(uint8_t(*first))) { + first++; + } +#endif + if (first == last || base < 2 || base > 36) { + answer.ec = std::errc::invalid_argument; + answer.ptr = first; + return answer; + } + return parse_int_string(first, last, value, base); +} + +} // namespace fast_float + +#endif + diff --git a/source/game/StarCommandProcessor.cpp b/source/game/StarCommandProcessor.cpp index 7b6915e..74fc33a 100644 --- a/source/game/StarCommandProcessor.cpp +++ b/source/game/StarCommandProcessor.cpp @@ -262,7 +262,7 @@ String CommandProcessor::setTileProtection(ConnectionId connectionId, String con return "Not enough arguments to /settileprotection. Use /settileprotection "; try { - bool isProtected = lexicalCast(arguments.takeLast()); + bool isProtected = Json::parse(arguments.takeLast()).toBool(); List dungeonIds; for (auto& banana : arguments) { auto slices = banana.split(".."); From 764751a82545a80688612b643ba8031f10b6c048 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 17 Sep 2024 00:04:54 +1000 Subject: [PATCH 023/181] Update README.md [skip ci] --- README.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 46bd8b2..04c2fa4 100644 --- a/README.md +++ b/README.md @@ -12,18 +12,20 @@ An installer is available for Windows. otherwise, extract the client/server zip ### Nightly Builds These link directly to the latest build from the [Actions](https://github.com/OpenStarbound/OpenStarbound/actions?query=branch%3Amain) tab. -[**Windows**](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build_windows/main): -[Installer](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build_windows/main/OpenStarbound-Windows-Installer.zip), +**Windows** +[Installer](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build/main/OpenStarbound-Windows-Installer.zip), [Client](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build_windows/main/OpenStarbound-Windows-Client.zip), [Server](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build_windows/main/OpenStarbound-Windows-Server.zip) -[**Linux**](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build_linux/main): -[Client](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build_linux/main/OpenStarbound-Linux-Client.zip), -[Server](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build_linux/main/OpenStarbound-Linux-Server.zip) +**Linux** +[Client](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build/main/OpenStarbound-Linux-Client.zip), +[Server](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build/main/OpenStarbound-Linux-Server.zip) -[**macOS**](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build_macos/main "overpriced aluminium"): -[Intel](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build_macos/main/OpenStarbound-Dev-macOS-Intel.zip), -[ARM](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build_macos/main/OpenStarbound-Dev-macOS-Silicon.zip) +**macOS** +[Intel](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build/main/OpenStarbound-Dev-macOS-Intel.zip), +[ARM](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build/main/OpenStarbound-Dev-macOS-Silicon.zip) + +[All Nightly Builds](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build/main) ## Changes Note: Not every function from [StarExtensions](https://github.com/StarExtensions/StarExtensions) has been ported yet, but near-full compatibility with mods that use StarExtensions features is planned. From ca48a137ec25f1002af4a1ab6e6e5047b5684ca6 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sun, 22 Sep 2024 15:59:45 +1000 Subject: [PATCH 024/181] root.assetFrames & assets.frames --- doc/lua/openstarbound.md | 4 +++- source/base/StarAssets.cpp | 14 ++++++++++++++ source/base/StarAssets.hpp | 3 ++- source/game/scripting/StarRootLuaBindings.cpp | 7 +++++++ source/game/scripting/StarRootLuaBindings.hpp | 1 + 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/doc/lua/openstarbound.md b/doc/lua/openstarbound.md index ad8483d..23c0bbb 100644 --- a/doc/lua/openstarbound.md +++ b/doc/lua/openstarbound.md @@ -76,7 +76,9 @@ Returns the asset source path of an asset, or nil if the asset doesn't exist. If Without metadata: Returns an array with all the asset source paths. With metadata: Returns a table, key/value being source path/metadata. -#### `?` root.assetImage(`String` image) +#### `Image` root.assetImage(`String` image) + +#### `Json` root.assetFrames(`String` path) *TODO* diff --git a/source/base/StarAssets.cpp b/source/base/StarAssets.cpp index 4a10aab..ecd2068 100644 --- a/source/base/StarAssets.cpp +++ b/source/base/StarAssets.cpp @@ -102,6 +102,14 @@ Maybe FramesSpecification::getRect(String const& frame) const { } } +Json FramesSpecification::toJson() const { + return JsonObject{ + {"aliases", jsonFromMap(aliases)}, + {"frames", jsonFromMapV(frames, jsonFromRectU)}, + {"file", framesFile} + }; +} + Assets::Assets(Settings settings, StringList assetSources) { const char* AssetsPatchSuffix = ".patch"; const char* AssetsPatchListSuffix = ".patchlist"; @@ -139,6 +147,12 @@ Assets::Assets(Settings settings, StringList assetSources) { return *assetImage; }); + callbacks.registerCallback("frames", [this](String const& path) -> Json { + if (auto frames = imageFrames(path)) + return frames->toJson(); + return Json(); + }); + callbacks.registerCallback("scan", [this](Maybe const& a, Maybe const& b) -> StringList { return b ? scan(a.value(), *b) : scan(a.value()); }); diff --git a/source/base/StarAssets.hpp b/source/base/StarAssets.hpp index 6b454e8..e7b8611 100644 --- a/source/base/StarAssets.hpp +++ b/source/base/StarAssets.hpp @@ -27,7 +27,8 @@ struct FramesSpecification { // Get the target sub-rect of a given frame name (which can be an alias). // Returns nothing if the frame name is not found. Maybe getRect(String const& frame) const; - + // Converts to Json. + Json toJson() const; // The full path to the .frames file from which this was loaded. String framesFile; // Named sub-frames diff --git a/source/game/scripting/StarRootLuaBindings.cpp b/source/game/scripting/StarRootLuaBindings.cpp index 0ce7866..e1d7e3e 100644 --- a/source/game/scripting/StarRootLuaBindings.cpp +++ b/source/game/scripting/StarRootLuaBindings.cpp @@ -33,6 +33,7 @@ LuaCallbacks LuaBindings::makeRootCallbacks() { callbacks.registerCallbackWithSignature("assetData", bind(RootCallbacks::assetData, root, _1)); callbacks.registerCallbackWithSignature("assetImage", bind(RootCallbacks::assetImage, root, _1)); + callbacks.registerCallbackWithSignature("assetFrames", bind(RootCallbacks::assetFrames, root, _1)); callbacks.registerCallbackWithSignature("assetJson", bind(RootCallbacks::assetJson, root, _1)); callbacks.registerCallbackWithSignature("makeCurrentVersionedJson", bind(RootCallbacks::makeCurrentVersionedJson, root, _1, _2)); callbacks.registerCallbackWithSignature("loadVersionedJson", bind(RootCallbacks::loadVersionedJson, root, _1, _2)); @@ -262,6 +263,12 @@ Image LuaBindings::RootCallbacks::assetImage(Root* root, String const& path) { return *root->assets()->image(path); } +Json LuaBindings::RootCallbacks::assetFrames(Root* root, String const& path) { + if (auto frames = root->assets()->imageFrames(path)) + return frames->toJson(); + return Json(); +} + Json LuaBindings::RootCallbacks::assetJson(Root* root, String const& path) { return root->assets()->json(path); } diff --git a/source/game/scripting/StarRootLuaBindings.hpp b/source/game/scripting/StarRootLuaBindings.hpp index 0cee77f..b3eeddc 100644 --- a/source/game/scripting/StarRootLuaBindings.hpp +++ b/source/game/scripting/StarRootLuaBindings.hpp @@ -15,6 +15,7 @@ namespace LuaBindings { namespace RootCallbacks { String assetData(Root* root, String const& path); Image assetImage(Root* root, String const& path); + Json assetFrames(Root* root, String const& path); Json assetJson(Root* root, String const& path); Json makeCurrentVersionedJson(Root* root, String const& identifier, Json const& content); Json loadVersionedJson(Root* root, Json const& versionedJson, String const& expectedIdentifier); From 3e8f914154b06af319ea7fffa633e0501f0e1f62 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sun, 22 Sep 2024 16:24:20 +1000 Subject: [PATCH 025/181] fix bool lexical casts oops --- source/core/StarLexicalCast.cpp | 23 +++++++++++++++++++++++ source/core/StarLexicalCast.hpp | 7 ++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/source/core/StarLexicalCast.cpp b/source/core/StarLexicalCast.cpp index 1387b2e..e607ee5 100644 --- a/source/core/StarLexicalCast.cpp +++ b/source/core/StarLexicalCast.cpp @@ -10,4 +10,27 @@ void throwLexicalCastError(std::errc ec, const char* first, const char* last) { throw BadLexicalCast(strf("Lexical cast failed on '{}'", str)); } +template <> +bool tryLexicalCast(bool& result, const char* first, const char* last) { + size_t len = last - first; + if (strncmp(first, "true", len) == 0) + result = true; + else if (strncmp(first, "false", len) != 0) + return false; + + result = false; + return true; +} + +template <> +bool lexicalCast(const char* first, const char* last) { + size_t len = last - first; + if (strncmp(first, "true", len) == 0) + return true; + else if (strncmp(first, "false", len) != 0) + throwLexicalCastError(std::errc(), first, last); + + return false; +} + } \ No newline at end of file diff --git a/source/core/StarLexicalCast.hpp b/source/core/StarLexicalCast.hpp index 13c0521..15afe3f 100644 --- a/source/core/StarLexicalCast.hpp +++ b/source/core/StarLexicalCast.hpp @@ -19,6 +19,9 @@ bool tryLexicalCast(Type& result, const char* first, const char* last) { return res.ptr == last && (res.ec == std::errc() || res.ec == std::errc::result_out_of_range); } +template <> +bool tryLexicalCast(bool& result, const char* first, const char* last); + template bool tryLexicalCast(Type& result, String const& s) { return tryLexicalCast(s.utf8Ptr(), s.utf8Ptr() + s.utf8Size()); @@ -43,7 +46,6 @@ Maybe maybeLexicalCast(StringView s) { return maybeLexicalCast(s.utf8Ptr(), s.utf8Ptr() + s.utf8Size()); } - template Type lexicalCast(const char* first, const char* last) { Type result{}; @@ -54,6 +56,9 @@ Type lexicalCast(const char* first, const char* last) { return result; } +template <> +bool lexicalCast(const char* first, const char* last); + template Type lexicalCast(StringView s) { return lexicalCast(s.utf8Ptr(), s.utf8Ptr() + s.utf8Size()); From 80192714b780a09291e00cd41152abef9c249859 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Wed, 2 Oct 2024 09:07:42 +1000 Subject: [PATCH 026/181] Update StarSongbookInterface.cpp --- source/frontend/StarSongbookInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/frontend/StarSongbookInterface.cpp b/source/frontend/StarSongbookInterface.cpp index 0c5fa4a..fa9a7c4 100644 --- a/source/frontend/StarSongbookInterface.cpp +++ b/source/frontend/StarSongbookInterface.cpp @@ -64,7 +64,7 @@ void SongbookInterface::refresh(bool reloadFiles) { m_files = Root::singleton().assets()->scanExtension(".abc").values(); eraseWhere(m_files, [](String& song) { if (!song.beginsWith(SongPathPrefix, String::CaseInsensitive)) { - Logger::warn("Song '{}' isn't in {}, ignoring", SongPathPrefix.size(), song); + Logger::warn("Song '{}' isn't in {}, ignoring", song, SongPathPrefix); return true; } return false; From 25f3edbae301eae0fd87162527e12cbb2630b022 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Wed, 2 Oct 2024 14:45:27 +1000 Subject: [PATCH 027/181] shipworlds: store their own epoch time for consistent plant growth --- source/game/StarUniverseServer.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/source/game/StarUniverseServer.cpp b/source/game/StarUniverseServer.cpp index 6961ce4..fa728fb 100644 --- a/source/game/StarUniverseServer.cpp +++ b/source/game/StarUniverseServer.cpp @@ -673,7 +673,6 @@ void UniverseServer::updateShips() { Json jOldShipLevel = shipWorld->getProperty("ship.level"); unsigned newShipLevel = min(speciesShips.size() - 1, newShipUpgrades.shipLevel); - if (jOldShipLevel.isType(Json::Type::Int)) { auto oldShipLevel = jOldShipLevel.toUInt(); if (oldShipLevel < newShipLevel) { @@ -2036,10 +2035,21 @@ Maybe> UniverseServer::shipWorldPromise( shipWorld->setProperty("ship.maxFuel", currentUpgrades.maxFuel); shipWorld->setProperty("ship.crewSize", currentUpgrades.crewSize); shipWorld->setProperty("ship.fuelEfficiency", currentUpgrades.fuelEfficiency); + shipWorld->setProperty("ship.epoch", Time::timeSinceEpoch()); + } + + auto shipClock = make_shared(); + auto shipTime = shipWorld->getProperty("ship.epoch"); + if (!shipTime.canConvert(Json::Type::Float)) { + auto now = Time::timeSinceEpoch(); + shipWorld->setProperty("ship.epoch", now); + } else { + shipClock->setTime(Time::timeSinceEpoch() - shipTime.toDouble()); } shipWorld->setUniverseSettings(m_universeSettings); - shipWorld->setReferenceClock(universeClock); + shipWorld->setReferenceClock(shipClock); + shipClock->start(); if (auto systemWorld = clientContext->systemWorld()) shipWorld->setOrbitalSky(systemWorld->clientSkyParameters(clientContext->clientId())); From 932ec4019a592ab0f87cf2c7790bfe66828dfccb Mon Sep 17 00:00:00 2001 From: Jenya Date: Wed, 2 Oct 2024 22:35:54 +0300 Subject: [PATCH 028/181] Actual code --- assets/opensb/binds/opensb.binds | 8 +++++++- source/frontend/StarContainerInterface.cpp | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/assets/opensb/binds/opensb.binds b/assets/opensb/binds/opensb.binds index c52385a..8a4fdc8 100644 --- a/assets/opensb/binds/opensb.binds +++ b/assets/opensb/binds/opensb.binds @@ -3,7 +3,8 @@ "groups": { "camera": { "name": "Camera" }, "voice": { "name": "Voice" }, - "building": { "name": "Building" } + "building": { "name": "Building" }, + "inventory": { "name": "Inventory" } }, "name": "Open^#ebd74a;Starbound", "binds": { @@ -15,6 +16,11 @@ "group": "camera", "name": "Zoom In" }, + "takeAll": { + "default": [], + "group": "inventory", + "name": "Take All From Container" + }, "zoomOut": { "default": [{ "type": "key", diff --git a/source/frontend/StarContainerInterface.cpp b/source/frontend/StarContainerInterface.cpp index 5a06d04..5d7ae89 100644 --- a/source/frontend/StarContainerInterface.cpp +++ b/source/frontend/StarContainerInterface.cpp @@ -18,6 +18,7 @@ #include "StarStatusControllerLuaBindings.hpp" #include "StarWidgetLuaBindings.hpp" #include "StarAugmentItem.hpp" +#include namespace Star { @@ -265,6 +266,7 @@ void ContainerPane::update(float dt) { m_script->update(m_script->updateDt(dt)); m_itemBag->clearItems(); + Input& input = Input::singleton(); if (!m_containerInteractor->containerOpen()) { dismiss(); @@ -296,6 +298,10 @@ void ContainerPane::update(float dt) { fuelGauge->setPotentialFuelAmount(totalFuelAmount); fuelGauge->setRequestedFuelAmount(0); } + + if (input.bindDown("opensb", "takeAll")) { + m_containerInteractor->clearContainer(); + } } } } From 03b7e3a22be9e1231072a5f6f8f559634f40f47f Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Fri, 4 Oct 2024 13:44:07 +1000 Subject: [PATCH 029/181] PlayerInventory: fix bag loading issue --- source/game/StarPlayerInventory.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/source/game/StarPlayerInventory.cpp b/source/game/StarPlayerInventory.cpp index 1edcdca..f64794d 100644 --- a/source/game/StarPlayerInventory.cpp +++ b/source/game/StarPlayerInventory.cpp @@ -781,19 +781,14 @@ void PlayerInventory::load(Json const& store) { //reuse ItemBags so the Inventory pane still works after load()'ing into the same PlayerInventory again (from swap) auto itemBags = store.get("itemBags").toObject(); - eraseWhere(m_bags, [&](auto const& p) { return !itemBags.contains(p.first); }); m_inventoryLoadOverflow.clear(); for (auto const& p : itemBags) { auto& bagType = p.first; auto newBag = ItemBag::loadStore(p.second); if (m_bags.contains(bagType)) { - auto& bag = m_bags[bagType]; - auto size = bag->size(); - if (bag) - *bag = std::move(newBag); - else - bag = make_shared(std::move(newBag)); - m_inventoryLoadOverflow.appendAll(bag->resize(size)); + auto& bag = m_bags.at(bagType); + m_inventoryLoadOverflow.appendAll(newBag.resize(bag->size())); + *bag = std::move(newBag); } else { m_inventoryLoadOverflow.appendAll(newBag.items()); } From c033774aa193501630c4d20edce52c860dd64884 Mon Sep 17 00:00:00 2001 From: SilverSokolova <80606782+SilverSokolova@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:53:02 -0500 Subject: [PATCH 030/181] Update README.md * Add answers for common installation questions ("Does it replace SB?", "Can I keep my characters and universe?", "Can I use Steam mods?") * Inform users of some bug fixes and command changes --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 04c2fa4..4aec7bc 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ It is still **work-in-progress**. ## Installation You can download a nightly build below, or the [latest release](https://github.com/OpenStarbound/OpenStarbound/releases/latest). At the moment, you must copy the game assets (**packed.pak**) from your normal Starbound install to the OpenStarbound assets directory before playing. +OpenStarbound is a separate installation/executable than Starbound. You can copy your `storage` folder from Starbound to transfer your save data and settings. Launching OpenStarbound with Steam open will load your subscribed Steam mods. + An installer is available for Windows. otherwise, extract the client/server zip for your platform and copy the game assets (packed.pak) to the OpenStarbound assets folder. the macOS releases currently lack the sbinit.config and folder structure that the Linux & Windows zips have, so you'll need to create those before running them. For macOS releases, it is recommended to build them from source (See guide below). ### Nightly Builds These link directly to the latest build from the [Actions](https://github.com/OpenStarbound/OpenStarbound/actions?query=branch%3Amain) tab. @@ -40,8 +42,16 @@ Note: Not every function from [StarExtensions](https://github.com/StarExtensions * These scripts can modify, read, patch and create new assets! * Lua patch files now exist - **.patch.lua** * These can patch JSON assets, as well as images! +### Commands +**View OpenStarbound commands with `/help`! You can also view them [here](https://github.com/OpenStarbound/OpenStarbound/blob/main/assets/opensb/help.config.patch)** + * Changes to vanilla commands: + * `/settileprotection` + * You can now specify as many dungeon IDs as you want: `/settileprotection 69 420 false` + * You can now specify a range: /settileprotection 0..65535 true ### Bug Fixes * Invalid character inventories are updated when loading in, allowing players to swap inventory mods with pre-existing characters. +* Fix vanilla world file size bloating issue. +* Modifying a single status property no longer re-networks every status property on the entity (server and client must be running at least OpenStarbound 0.15) ### Misc * Player functions for saving/loading, modifying the humanoid identity, manipulating the inventory. [Documentation](https://github.com/OpenStarbound/OpenStarbound/blob/main/doc/lua/openstarbound.md) * Character swapping (rewrite from StarExtensions, currently command-only: `/swap name` case-insensitive, only substring required) From 11b91ff84f3dcce737ded182eeb442c4cd228a35 Mon Sep 17 00:00:00 2001 From: SilverSokolova <80606782+SilverSokolova@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:02:46 -0500 Subject: [PATCH 031/181] Documentation: Fix player.setActionBarSlotLink doc and add player.currentState --- doc/lua/openstarbound.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/doc/lua/openstarbound.md b/doc/lua/openstarbound.md index 23c0bbb..b5ceef0 100644 --- a/doc/lua/openstarbound.md +++ b/doc/lua/openstarbound.md @@ -394,9 +394,9 @@ Returns whether the specified item can enter the specified item bag. Returns the contents of the specified action bar link slot's specified hand. -#### `bool` player.setActionBarSlotLink(`String` itemBagName, `ItemDescriptor` item) +#### `bool` player.setActionBarSlotLink(`int` slot, `String` hand, `ItemSlot` itemSlot) -Returns whether the specified item can enter the specified item bag. +Links the specified slot's hand to the specified itemSlot. --- @@ -415,3 +415,21 @@ Sets the player's interact radius. This does not persist upon returning to the m Returns all the recipes the player can craft with their currently held items and currencies. --- +#### `String` player.currentState() + +Returns the player's current movement state. + +
Player States +idle
+walk
+run
+jump
+fall
+swim
+swimIdle
+lounge
+crouch
+teleportIn
+teleportOut
+
+--- From 5db9e4e1c582d39096aa9faf5f84c5aa73eb5cc9 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 8 Oct 2024 09:49:52 +1100 Subject: [PATCH 032/181] Fix keypad binding issue (#125) --- source/frontend/StarKeybindingsMenu.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/source/frontend/StarKeybindingsMenu.cpp b/source/frontend/StarKeybindingsMenu.cpp index c07dae8..b532ca9 100644 --- a/source/frontend/StarKeybindingsMenu.cpp +++ b/source/frontend/StarKeybindingsMenu.cpp @@ -180,14 +180,18 @@ void KeybindingsMenu::setKeybinding(KeyChord desc) { config->set("bindings", base); - String buttonText; + StringList buttonText; for (auto const& entry : base.get(key).iterateArray()) { - auto stored = inputDescriptorFromJson(entry); - buttonText = String::joinWith(", ", buttonText, printInputDescriptor(stored)); + try { + auto stored = inputDescriptorFromJson(entry); + buttonText.push_back(printInputDescriptor(stored)); + } catch (StarException const& e) { + buttonText.push_back("unknown"); + } } - convert(m_activeKeybinding)->setText(buttonText); + convert(m_activeKeybinding)->setText(buttonText.join(", ")); apply(); exitActiveMode(); From c9d45daac951f46ba59633ec394bdc92876c1e79 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Fri, 11 Oct 2024 05:16:09 +1100 Subject: [PATCH 033/181] Don't trigger player slot reordering when autosaving after swapped --- source/game/StarUniverseClient.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/game/StarUniverseClient.cpp b/source/game/StarUniverseClient.cpp index 6038901..19b78cd 100644 --- a/source/game/StarUniverseClient.cpp +++ b/source/game/StarUniverseClient.cpp @@ -288,7 +288,8 @@ void UniverseClient::update(float dt) { if (Time::monotonicMilliseconds() >= m_storageTriggerDeadline) { if (m_mainPlayer) { m_playerStorage->savePlayer(m_mainPlayer); - m_playerStorage->moveToFront(m_mainPlayer->uuid()); + if (playerIsOriginal()) + m_playerStorage->moveToFront(m_mainPlayer->uuid()); } m_storageTriggerDeadline = Time::monotonicMilliseconds() + assets->json("/client.config:storageTriggerInterval").toUInt(); From 8eea7862aa9d1122c127786f53b9a6d4d15bade2 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Fri, 11 Oct 2024 05:32:44 +1100 Subject: [PATCH 034/181] Update README.md [skip ci] --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4aec7bc..fc911bf 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,8 @@ These link directly to the latest build from the [Actions](https://github.com/Op **Windows** [Installer](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build/main/OpenStarbound-Windows-Installer.zip), -[Client](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build_windows/main/OpenStarbound-Windows-Client.zip), -[Server](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build_windows/main/OpenStarbound-Windows-Server.zip) +[Client](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build/main/OpenStarbound-Windows-Client.zip), +[Server](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build/main/OpenStarbound-Windows-Server.zip) **Linux** [Client](https://nightly.link/OpenStarbound/OpenStarbound/workflows/build/main/OpenStarbound-Linux-Client.zip), From 9e2f39bc01ef733d8b6358db2e199a25c4795193 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Fri, 11 Oct 2024 05:34:45 +1100 Subject: [PATCH 035/181] Update StarContainerInterface.cpp --- source/frontend/StarContainerInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/frontend/StarContainerInterface.cpp b/source/frontend/StarContainerInterface.cpp index 5d7ae89..afd2084 100644 --- a/source/frontend/StarContainerInterface.cpp +++ b/source/frontend/StarContainerInterface.cpp @@ -18,7 +18,7 @@ #include "StarStatusControllerLuaBindings.hpp" #include "StarWidgetLuaBindings.hpp" #include "StarAugmentItem.hpp" -#include +#include "StarInput.hpp" namespace Star { From be884c33b497ba6ca92f81f68465367969ff663a Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 15 Oct 2024 16:11:17 +1100 Subject: [PATCH 036/181] change ImageMetadataDatabase caches to use a TTL --- source/game/StarImageMetadataDatabase.cpp | 65 ++++++++++++++--------- source/game/StarImageMetadataDatabase.hpp | 9 ++-- source/game/StarRoot.cpp | 7 +++ 3 files changed, 53 insertions(+), 28 deletions(-) diff --git a/source/game/StarImageMetadataDatabase.cpp b/source/game/StarImageMetadataDatabase.cpp index d04e984..af6ec49 100644 --- a/source/game/StarImageMetadataDatabase.cpp +++ b/source/game/StarImageMetadataDatabase.cpp @@ -10,17 +10,28 @@ namespace Star { +ImageMetadataDatabase::ImageMetadataDatabase() { + MutexLocker locker(m_mutex); + int timeSmear = 2000; + int64_t timeToLive = 60000; + m_sizeCache.setTimeSmear(timeSmear); + m_spacesCache.setTimeSmear(timeSmear); + m_regionCache.setTimeSmear(timeSmear); + m_sizeCache.setTimeToLive(timeToLive); + m_spacesCache.setTimeToLive(timeToLive); + m_regionCache.setTimeToLive(timeToLive); +} + Vec2U ImageMetadataDatabase::imageSize(AssetPath const& path) const { MutexLocker locker(m_mutex); - auto i = m_sizeCache.find(path); - if (i != m_sizeCache.end()) - return i->second; + if (auto cached = m_sizeCache.ptr(path)) + return *cached; locker.unlock(); Vec2U size = calculateImageSize(path); locker.lock(); - m_sizeCache[path] = size; + m_sizeCache.set(path, size); return size; } @@ -28,19 +39,16 @@ List ImageMetadataDatabase::imageSpaces(AssetPath const& path, Vec2F posi SpacesEntry key = make_tuple(path, Vec2I::round(position), fillLimit, flip); MutexLocker locker(m_mutex); - auto i = m_spacesCache.find(key); - if (i != m_spacesCache.end()) { - return i->second; + if (auto cached = m_spacesCache.ptr(key)) { + return *cached; } auto filteredPath = filterProcessing(path); SpacesEntry filteredKey = make_tuple(filteredPath, Vec2I::round(position), fillLimit, flip); - auto j = m_spacesCache.find(filteredKey); - if (j != m_spacesCache.end()) { - auto spaces = j->second; - m_spacesCache[key] = spaces; - return spaces; + if (auto cached = m_spacesCache.ptr(filteredKey)) { + m_spacesCache.set(key, *cached); + return *cached; } locker.unlock(); @@ -82,24 +90,23 @@ List ImageMetadataDatabase::imageSpaces(AssetPath const& path, Vec2F posi } locker.lock(); - m_spacesCache[key] = spaces; - m_spacesCache[filteredKey] = spaces; + m_spacesCache.set(key, spaces); + m_spacesCache.set(filteredKey, spaces); return spaces; } RectU ImageMetadataDatabase::nonEmptyRegion(AssetPath const& path) const { MutexLocker locker(m_mutex); - auto i = m_regionCache.find(path); - if (i != m_regionCache.end()) { - return i->second; + + if (auto cached = m_regionCache.ptr(path)) { + return *cached; } auto filteredPath = filterProcessing(path); - auto j = m_regionCache.find(filteredPath); - if (j != m_regionCache.end()) { - m_regionCache[path] = j->second; - return j->second; + if (auto cached = m_regionCache.ptr(filteredPath)) { + m_regionCache.set(path, *cached); + return *cached; } locker.unlock(); @@ -111,12 +118,20 @@ RectU ImageMetadataDatabase::nonEmptyRegion(AssetPath const& path) const { }); locker.lock(); - m_regionCache[path] = region; - m_regionCache[filteredPath] = region; + m_regionCache.set(path, region); + m_regionCache.set(filteredPath, region); return region; } +void ImageMetadataDatabase::cleanup() const { + MutexLocker locker(m_mutex); + + m_sizeCache.cleanup(); + m_spacesCache.cleanup(); + m_regionCache.cleanup(); +} + AssetPath ImageMetadataDatabase::filterProcessing(AssetPath const& path) { AssetPath newPath = { path.basePath, path.subPath, {} }; @@ -170,7 +185,7 @@ Vec2U ImageMetadataDatabase::calculateImageSize(AssetPath const& path) const { // so we don't have to call Image::readPngMetadata on the same file more // than once. MutexLocker locker(m_mutex); - if (auto size = m_sizeCache.maybe(path.basePath)) { + if (auto size = m_sizeCache.ptr(path.basePath)) { imageSize = *size; } else { locker.unlock(); @@ -180,7 +195,7 @@ Vec2U ImageMetadataDatabase::calculateImageSize(AssetPath const& path) const { else imageSize = fallback(); locker.lock(); - m_sizeCache[path.basePath] = imageSize; + m_sizeCache.set(path.basePath, imageSize); } } diff --git a/source/game/StarImageMetadataDatabase.hpp b/source/game/StarImageMetadataDatabase.hpp index 69e7a07..0a04b1f 100644 --- a/source/game/StarImageMetadataDatabase.hpp +++ b/source/game/StarImageMetadataDatabase.hpp @@ -5,6 +5,7 @@ #include "StarString.hpp" #include "StarThread.hpp" #include "StarAssetPath.hpp" +#include "StarTtlCache.hpp" namespace Star { @@ -15,9 +16,11 @@ STAR_CLASS(ImageMetadataDatabase); // because they are expensive to compute and cheap to keep around. class ImageMetadataDatabase { public: + ImageMetadataDatabase(); Vec2U imageSize(AssetPath const& path) const; List imageSpaces(AssetPath const& path, Vec2F position, float fillLimit, bool flip) const; RectU nonEmptyRegion(AssetPath const& path) const; + void cleanup() const; private: // Removes image processing directives that don't affect image spaces / @@ -30,9 +33,9 @@ private: typedef tuple SpacesEntry; mutable Mutex m_mutex; - mutable HashMap m_sizeCache; - mutable HashMap> m_spacesCache; - mutable HashMap m_regionCache; + mutable HashTtlCache m_sizeCache; + mutable HashTtlCache> m_spacesCache; + mutable HashTtlCache m_regionCache; }; } diff --git a/source/game/StarRoot.cpp b/source/game/StarRoot.cpp index 626e298..a260dbb 100644 --- a/source/game/StarRoot.cpp +++ b/source/game/StarRoot.cpp @@ -137,6 +137,13 @@ Root::Root(Settings settings) : RootBase() { tenantDb->cleanup(); } } + { + MutexLocker locker(m_imageMetadataDatabaseMutex); + if (ImageMetadataDatabasePtr imgMetaDb = m_imageMetadataDatabase) { + locker.unlock(); + imgMetaDb->cleanup(); + } + } Random::addEntropy(); From 8aedf51957689d37250f21279df8376d57414cee Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 15 Oct 2024 16:16:57 +1100 Subject: [PATCH 037/181] add new quest Lua bindings to player --- source/game/StarQuestManager.cpp | 68 ++++++++++++------- source/game/StarQuestManager.hpp | 5 +- .../game/scripting/StarPlayerLuaBindings.cpp | 34 +++++++++- 3 files changed, 79 insertions(+), 28 deletions(-) diff --git a/source/game/StarQuestManager.cpp b/source/game/StarQuestManager.cpp index e9736c7..876f0b8 100644 --- a/source/game/StarQuestManager.cpp +++ b/source/game/StarQuestManager.cpp @@ -73,7 +73,11 @@ void QuestManager::setUniverseClient(UniverseClient* client) { void QuestManager::init(World* world) { m_world = world; - serverQuests().exec([this, world](QuestPtr const& quest) { quest->init(m_player, world, m_client); }); + for (auto& quest : m_quests) { + if (!questValidOnServer(quest.second)) + continue; + quest.second->init(m_player, world, m_client); + } m_trackOnWorldQuests = true; // untrack tracked quest if it's not cross-server, and we're on a different server @@ -124,6 +128,21 @@ void QuestManager::offer(QuestPtr const& quest) { quest->offer(); } +StringMap QuestManager::quests() const { + return m_quests; +} + +StringMap QuestManager::serverQuests() const { + StringMap filtered; + for (auto& pair : m_quests) { + QuestPtr q = pair.second; + if (!questValidOnServer(q)) + continue; + filtered.insert(pair.first, q); + } + return filtered; +} + QuestPtr QuestManager::getQuest(String const& questId) const { return m_quests.get(questId); } @@ -184,33 +203,33 @@ bool QuestManager::canTurnIn(String const& questId) const { } Maybe QuestManager::getFirstNewQuest() { - for (auto& q : serverQuests()) { - if (q->state() == QuestState::Offer) - return q; + for (auto& q : m_quests) { + if (questValidOnServer(q.second) && q.second->state() == QuestState::Offer) + return q.second; } return {}; } Maybe QuestManager::getFirstCompletableQuest() { - for (auto& q : serverQuests()) { - if (q->state() == QuestState::Complete && q->showDialog()) - return q; + for (auto& q : m_quests) { + if (questValidOnServer(q.second) && q.second->state() == QuestState::Complete && q.second->showDialog()) + return q.second; } return {}; } Maybe QuestManager::getFirstFailableQuest() { - for (auto& q : serverQuests()) { - if (q->state() == QuestState::Failed&& q->showDialog()) - return q; + for (auto& q : m_quests) { + if (questValidOnServer(q.second) && q.second->state() == QuestState::Failed && q.second->showDialog()) + return q.second; } return {}; } Maybe QuestManager::getFirstMainQuest() { - for (auto& q : serverQuests()) { - if (q->state() == QuestState::Active && q->mainQuest()) - return q; + for (auto& q : m_quests) { + if (questValidOnServer(q.second) && q.second->state() == QuestState::Active && q.second->mainQuest()) + return q.second; } return {}; } @@ -228,7 +247,7 @@ void sortQuests(List& quests) { } List QuestManager::listActiveQuests() const { - List result = serverQuests(); + List result = serverQuests().values(); result.filter([&](QuestPtr quest) { return quest->state() == QuestState::Active && quest->showInLog(); }); @@ -237,7 +256,7 @@ List QuestManager::listActiveQuests() const { } List QuestManager::listCompletedQuests() const { - List result = serverQuests(); + List result = serverQuests().values(); result.filter([](QuestPtr quest) { return quest->state() == QuestState::Complete && quest->showInLog(); }); @@ -246,7 +265,7 @@ List QuestManager::listCompletedQuests() const { } List QuestManager::listFailedQuests() const { - List result = serverQuests(); + List result = serverQuests().values(); result.filter([](QuestPtr quest) { return quest->state() == QuestState::Failed && quest->showInLog(); }); @@ -381,15 +400,10 @@ void QuestManager::update(float dt) { } } - serverQuests().exec([dt](QuestPtr const& quest) { quest->update(dt); }); -} - -List QuestManager::serverQuests() const { - return m_quests.values().filtered([this](QuestPtr const& q) -> bool { - if (q->hideCrossServer() && q->serverUuid().isValid() && *q->serverUuid() != m_player->clientContext()->serverUuid()) - return false; - return true; - }); + for (auto& q : m_quests) { + if (questValidOnServer(q.second)) + q.second->update(dt); + } } void QuestManager::startInitialQuests() { @@ -408,4 +422,8 @@ void QuestManager::setMostRecentQuestCurrent() { setAsTracked(sortedActiveQuests.last()->questId()); } +bool QuestManager::questValidOnServer(QuestPtr q) const { + return !(q->hideCrossServer() && q->serverUuid().isValid() && *q->serverUuid() != m_player->clientContext()->serverUuid()); +} + } diff --git a/source/game/StarQuestManager.hpp b/source/game/StarQuestManager.hpp index 1dfcb2c..3d7ee22 100644 --- a/source/game/StarQuestManager.hpp +++ b/source/game/StarQuestManager.hpp @@ -28,6 +28,9 @@ public: // Show a dialog offering the player a quest, and later start it if they // accept it. void offer(QuestPtr const& quest); + StringMap quests() const; + // Only returns quests that are exclusive to the current server. + StringMap serverQuests() const; QuestPtr getQuest(String const& questId) const; bool hasQuest(String const& questId) const; @@ -60,9 +63,9 @@ public: void update(float dt); private: - List serverQuests() const; void startInitialQuests(); void setMostRecentQuestCurrent(); + bool questValidOnServer(QuestPtr quest) const; Player* m_player; World* m_world; diff --git a/source/game/scripting/StarPlayerLuaBindings.cpp b/source/game/scripting/StarPlayerLuaBindings.cpp index a6da4cc..7952f30 100644 --- a/source/game/scripting/StarPlayerLuaBindings.cpp +++ b/source/game/scripting/StarPlayerLuaBindings.cpp @@ -453,6 +453,21 @@ LuaCallbacks LuaBindings::makePlayerCallbacks(Player* player) { return followUp->questId(); }); + callbacks.registerCallback("questIds", [player]() { + return player->questManager()->quests().keys(); + }); + + callbacks.registerCallback("serverQuestIds", [player]() { + return player->questManager()->serverQuests().keys(); + }); + + callbacks.registerCallback("quest", [player](String const& questId) -> Json { + if (!player->questManager()->hasQuest(questId)) + return {}; + + return player->questManager()->getQuest(questId)->diskStore(); + }); + callbacks.registerCallback("hasQuest", [player](String const& questId) { return player->questManager()->hasQuest(questId); }); @@ -469,11 +484,26 @@ LuaCallbacks LuaBindings::makePlayerCallbacks(Player* player) { return player->questManager()->hasCompleted(questId); }); + callbacks.registerCallback("setTrackedQuest", [player](Maybe const& questId) { + return player->questManager()->setAsTracked(questId); + }); + + callbacks.registerCallback("canTurnInQuest", [player](String const& questId) { + return player->questManager()->canTurnIn(questId); + }); + + callbacks.registerCallback("currentQuest", [player]() -> Json { + auto maybeQuest = player->questManager()->currentQuest(); + if (maybeQuest) { + return (*maybeQuest)->diskStore(); + } + return {}; + }); + callbacks.registerCallback("currentQuestWorld", [player]() -> Maybe { auto maybeQuest = player->questManager()->currentQuest(); if (maybeQuest) { - auto quest = *maybeQuest; - if (auto worldId = quest->worldId()) + if (auto worldId = (*maybeQuest)->worldId()) return printWorldId(*worldId); } return {}; From 9ba9eb2ac33a53a8fd50ce14d40be00d42a9f7af Mon Sep 17 00:00:00 2001 From: LDA Date: Thu, 17 Oct 2024 00:16:44 -0700 Subject: [PATCH 038/181] only set minimum opengl context version on macos --- source/application/StarMainApplication_sdl.cpp | 4 +++- source/application/StarRenderer_opengl.cpp | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/source/application/StarMainApplication_sdl.cpp b/source/application/StarMainApplication_sdl.cpp index 6b0ca4c..557e02d 100644 --- a/source/application/StarMainApplication_sdl.cpp +++ b/source/application/StarMainApplication_sdl.cpp @@ -314,10 +314,12 @@ public: int height; SDL_GetWindowSize(m_sdlWindow, &width, &height); m_windowSize = Vec2U(width, height); - + +#ifdef __APPLE__ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); +#endif m_sdlGlContext = SDL_GL_CreateContext(m_sdlWindow); if (!m_sdlGlContext) diff --git a/source/application/StarRenderer_opengl.cpp b/source/application/StarRenderer_opengl.cpp index 0c9e7ec..9d0d717 100644 --- a/source/application/StarRenderer_opengl.cpp +++ b/source/application/StarRenderer_opengl.cpp @@ -107,8 +107,10 @@ OpenGlRenderer::OpenGlRenderer() { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_DEPTH_TEST); - //glEnable(GL_DEBUG_OUTPUT); - //glDebugMessageCallback(GlMessageCallback, this); + if (GLEW_VERSION_4_3) { + //glEnable(GL_DEBUG_OUTPUT); + //glDebugMessageCallback(GlMessageCallback, this); + } m_whiteTexture = createGlTexture(Image::filled({1, 1}, Vec4B(255, 255, 255, 255), PixelFormat::RGBA32), TextureAddressing::Clamp, From 0a5e92ef389a67956b1075cf7e4f0c3b2461c190 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 17 Oct 2024 19:02:24 +1100 Subject: [PATCH 039/181] unify UniverseClient & WorldClient LuaRoots & let universeClient scripts intercept packets can be used for intercepting chat packets, for example! --- source/game/StarUniverseClient.cpp | 36 ++++++++++++++----- source/game/StarUniverseClient.hpp | 2 -- source/game/StarWorldClient.cpp | 18 +++++----- source/game/StarWorldClient.hpp | 5 +-- .../game/scripting/StarWorldLuaBindings.cpp | 2 ++ 5 files changed, 38 insertions(+), 25 deletions(-) diff --git a/source/game/StarUniverseClient.cpp b/source/game/StarUniverseClient.cpp index 19b78cd..d739f5a 100644 --- a/source/game/StarUniverseClient.cpp +++ b/source/game/StarUniverseClient.cpp @@ -28,11 +28,17 @@ namespace Star { UniverseClient::UniverseClient(PlayerStoragePtr playerStorage, StatisticsPtr statistics) { + auto& root = Root::singleton(); + auto assets = root.assets(); + m_storageTriggerDeadline = 0; m_playerStorage = std::move(playerStorage); m_statistics = std::move(statistics); m_pause = false; m_luaRoot = make_shared(); + + auto clientConfig = assets->json("/client.config"); + m_luaRoot->tuneAutoGarbageCollection(clientConfig.getFloat("luaGcPause"), clientConfig.getFloat("luaGcStepMultiplier")); reset(); } @@ -151,11 +157,9 @@ Maybe UniverseClient::connect(UniverseConnection connection, bool allowA m_teamClient = make_shared(m_mainPlayer, m_clientContext); m_mainPlayer->setClientContext(m_clientContext); m_mainPlayer->setStatistics(m_statistics); - m_worldClient = make_shared(m_mainPlayer); + m_worldClient = make_shared(m_mainPlayer, m_luaRoot); m_worldClient->clientState().setNetCompatibilityRules(compatibilityRules); m_worldClient->setAsyncLighting(true); - for (auto& pair : m_luaCallbacks) - m_worldClient->setLuaCallbacks(pair.first, pair.second); m_connection = std::move(connection); m_celestialDatabase = make_shared(std::move(success->celestialInformation)); @@ -489,13 +493,13 @@ uint16_t UniverseClient::maxPlayers() { } void UniverseClient::setLuaCallbacks(String const& groupName, LuaCallbacks const& callbacks) { - m_luaCallbacks[groupName] = callbacks; - if (m_worldClient) - m_worldClient->setLuaCallbacks(groupName, callbacks); + m_luaRoot->addCallbacks(groupName, callbacks); } void UniverseClient::startLua() { + m_luaRoot->restart(); setLuaCallbacks("celestial", LuaBindings::makeCelestialCallbacks(this)); + setLuaCallbacks("world", LuaBindings::makeWorldCallbacks(m_worldClient.get())); auto assets = Root::singleton().assets(); for (auto& p : assets->json("/client.config:universeScriptContexts").toObject()) { @@ -503,9 +507,6 @@ void UniverseClient::startLua() { scriptComponent->setLuaRoot(m_luaRoot); scriptComponent->setScripts(jsonToStringList(p.second.toArray())); - for (auto& pair : m_luaCallbacks) - scriptComponent->addCallbacks(pair.first, pair.second); - m_scriptContexts.set(p.first, scriptComponent); scriptComponent->init(); } @@ -662,6 +663,23 @@ void UniverseClient::setPause(bool pause) { void UniverseClient::handlePackets(List const& packets) { for (auto const& packet : packets) { try { + bool skip = false; + Maybe packetJson; + auto functionName = strf("on{}Packet", PacketTypeNames.getRight(packet->type())); + for (auto& context : m_scriptContexts) { + auto& luaContext = *context.second->context(); + auto method = luaContext.get(functionName); + if (method != LuaNil) { + if (!packetJson) + packetJson = packet->writeJson(); + if (skip = luaContext.luaTo(std::move(method)).invoke(*packetJson).maybe().value()) { + break; + } + } + } + if (skip) + continue; + if (auto clientContextUpdate = as(packet)) { m_clientContext->readUpdate(clientContextUpdate->updateData, m_clientContext->netCompatibilityRules()); m_playerStorage->applyShipUpdates(m_clientContext->playerUuid(), m_clientContext->newShipUpdates()); diff --git a/source/game/StarUniverseClient.hpp b/source/game/StarUniverseClient.hpp index 6a85cdb..3a3860d 100644 --- a/source/game/StarUniverseClient.hpp +++ b/source/game/StarUniverseClient.hpp @@ -132,8 +132,6 @@ private: SystemWorldClientPtr m_systemWorldClient; Maybe m_connection; Maybe m_serverInfo; - - StringMap m_luaCallbacks; CelestialSlaveDatabasePtr m_celestialDatabase; ClientContextPtr m_clientContext; diff --git a/source/game/StarWorldClient.cpp b/source/game/StarWorldClient.cpp index d5c6bd7..d3e5c0c 100644 --- a/source/game/StarWorldClient.cpp +++ b/source/game/StarWorldClient.cpp @@ -28,7 +28,7 @@ const std::string SECRET_BROADCAST_PUBLIC_KEY = "SecretBroadcastPublicKey"; const std::string SECRET_BROADCAST_PREFIX = "\0Broadcast\0"s; const float WorldClient::DropDist = 6.0f; -WorldClient::WorldClient(PlayerPtr mainPlayer) { +WorldClient::WorldClient(PlayerPtr mainPlayer, LuaRootPtr luaRoot) { auto& root = Root::singleton(); auto assets = root.assets(); @@ -48,7 +48,7 @@ WorldClient::WorldClient(PlayerPtr mainPlayer) { m_collisionDebug = false; m_inWorld = false; - m_luaRoot = make_shared(); + m_luaRoot = luaRoot; m_mainPlayer = mainPlayer; @@ -1076,10 +1076,6 @@ List WorldClient::getOutgoingPackets() { return std::move(m_outgoingPackets); } -void WorldClient::setLuaCallbacks(String const& groupName, LuaCallbacks const& callbacks) { - m_luaRoot->addCallbacks(groupName, callbacks); -} - void WorldClient::update(float dt) { if (!inWorld()) return; @@ -1765,8 +1761,6 @@ void WorldClient::initWorld(WorldStartPacket const& startPacket) { return m_tileArray->tile(pos); }; m_damageManager = make_shared(this, startPacket.clientId); - m_luaRoot->restart(); - m_luaRoot->tuneAutoGarbageCollection(m_clientConfig.getFloat("luaGcPause"), m_clientConfig.getFloat("luaGcStepMultiplier")); m_playerStart = startPacket.playerRespawn; m_respawnInWorld = startPacket.respawnInWorld; m_worldProperties = startPacket.worldProperties.optObject().value(); @@ -1841,8 +1835,6 @@ void WorldClient::clearWorld() { m_damageManager.reset(); - m_luaRoot->shutdown(); - m_particles.reset(); m_sky.reset(); @@ -2244,6 +2236,9 @@ LuaRootPtr WorldClient::luaRoot() { } RpcPromise WorldClient::findUniqueEntity(String const& uniqueId) { + if (!inWorld()) + return RpcPromise::createFailed("Not currently in a world"); + if (auto entity = m_entityMap->uniqueEntity(uniqueId)) return RpcPromise::createFulfilled(entity->position()); @@ -2257,6 +2252,9 @@ RpcPromise WorldClient::findUniqueEntity(String const& uniqueId) { } RpcPromise WorldClient::sendEntityMessage(Variant const& entityId, String const& message, JsonArray const& args) { + if (!inWorld()) + return RpcPromise::createFailed("Not currently in a world"); + EntityPtr entity; if (entityId.is()) entity = m_entityMap->entity(entityId.get()); diff --git a/source/game/StarWorldClient.hpp b/source/game/StarWorldClient.hpp index 2957661..502a928 100644 --- a/source/game/StarWorldClient.hpp +++ b/source/game/StarWorldClient.hpp @@ -38,7 +38,7 @@ STAR_EXCEPTION(WorldClientException, StarException); class WorldClient : public World { public: - WorldClient(PlayerPtr mainPlayer); + WorldClient(PlayerPtr mainPlayer, LuaRootPtr luaRoot); ~WorldClient(); ConnectionId connection() const override; @@ -134,9 +134,6 @@ public: void handleIncomingPackets(List const& packets); List getOutgoingPackets(); - - // Sets default callbacks in the LuaRoot. - void setLuaCallbacks(String const& groupName, LuaCallbacks const& callbacks); // Set the rendering window for this client. void setClientWindow(RectI window); diff --git a/source/game/scripting/StarWorldLuaBindings.cpp b/source/game/scripting/StarWorldLuaBindings.cpp index 08a7a43..624660f 100644 --- a/source/game/scripting/StarWorldLuaBindings.cpp +++ b/source/game/scripting/StarWorldLuaBindings.cpp @@ -356,6 +356,8 @@ namespace LuaBindings { }); if (auto clientWorld = as(world)) { + callbacks.registerCallback("inWorld", [clientWorld]() { return clientWorld->inWorld(); }); + callbacks.registerCallback("mainPlayer", [clientWorld]() { return clientWorld->clientState().playerId(); }); callbacks.registerCallback("isClient", []() { return true; }); callbacks.registerCallback("isServer", []() { return false; }); callbacks.registerCallbackWithSignature("clientWindow", bind(ClientWorldCallbacks::clientWindow, clientWorld)); From aac3e5394157a0b55a6512cb2b94b20a57c1b98e Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Fri, 18 Oct 2024 14:18:40 +1100 Subject: [PATCH 040/181] win: add minidumps to fatal errors --- assets/opensb/interface.config.patch | 1 + source/core/StarSignalHandler_windows.cpp | 33 ++++++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/assets/opensb/interface.config.patch b/assets/opensb/interface.config.patch index eedd728..a43a7bc 100644 --- a/assets/opensb/interface.config.patch +++ b/assets/opensb/interface.config.patch @@ -41,6 +41,7 @@ // Change planet name to support the new internal string formatting. "planetNameFormatString" : "- {} -", + "planetTextOffset" : [0, 120], "planetTextStyle" : { "backDirectives" : "border=5;fff;fff?border=1;fff;fff7?multiply=000", "fontSize" : 24 diff --git a/source/core/StarSignalHandler_windows.cpp b/source/core/StarSignalHandler_windows.cpp index 29e93c5..13a36ac 100644 --- a/source/core/StarSignalHandler_windows.cpp +++ b/source/core/StarSignalHandler_windows.cpp @@ -4,11 +4,35 @@ #include "StarLogging.hpp" #include +#include "minidumpapiset.h" namespace Star { String g_sehMessage; +static DWORD WINAPI writeMiniDump(void* ExceptionInfo) { + auto hFile = CreateFileA("starbound.dmp", GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + if (hFile == INVALID_HANDLE_VALUE) + return 0; + MINIDUMP_EXCEPTION_INFORMATION dumpExceptionInfo{}; + dumpExceptionInfo.ThreadId = GetCurrentThreadId(); + dumpExceptionInfo.ExceptionPointers = (PEXCEPTION_POINTERS)ExceptionInfo; + dumpExceptionInfo.ClientPointers = FALSE; + MiniDumpWriteDump( + GetCurrentProcess(), + GetCurrentProcessId(), + hFile, + MiniDumpNormal, + &dumpExceptionInfo, + NULL, + NULL); + CloseHandle(hFile); + if (dumpExceptionInfo.ExceptionPointers->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) { + MessageBoxA(NULL, "Stack overflow encountered\nA minidump has been generated", NULL, MB_OK | MB_ICONERROR | MB_SETFOREGROUND); + } + return 0; +}; + struct SignalHandlerImpl { bool handlingFatal; bool handlingInterrupt; @@ -98,9 +122,7 @@ struct SignalHandlerImpl { } static LONG CALLBACK vectoredExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) { - if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) { - fatalError("Stack overflow encountered", false); - } + auto thread = CreateThread(NULL, 0, writeMiniDump, (void*)ExceptionInfo, 0, NULL); if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { handleFatalError("Access violation detected", ExceptionInfo); return EXCEPTION_CONTINUE_EXECUTION; @@ -143,7 +165,10 @@ struct SignalHandlerImpl { handleFatalError("Error occured", ExceptionInfo); return EXCEPTION_CONTINUE_EXECUTION; } - + if (thread != NULL) { + WaitForSingleObject(thread, 10000); + CloseHandle(thread); + } return EXCEPTION_CONTINUE_SEARCH; } From f270c3f1686923531058badf2e33633e54929d85 Mon Sep 17 00:00:00 2001 From: Degranon Date: Sat, 19 Oct 2024 21:10:39 +0500 Subject: [PATCH 041/181] Player teammembers --- doc/lua/player.md | 6 ++++++ source/game/StarPlayer.cpp | 16 ++++++++++++++++ source/game/StarPlayer.hpp | 2 ++ source/game/scripting/StarPlayerLuaBindings.cpp | 2 ++ 4 files changed, 26 insertions(+) diff --git a/doc/lua/player.md b/doc/lua/player.md index fd8ebd4..f281bad 100644 --- a/doc/lua/player.md +++ b/doc/lua/player.md @@ -527,3 +527,9 @@ Returns uuid, type, and orbits for all system objects in the specified system; #### `List` player.collectables(`String` collectionName) Returns a list of names of the collectables the player has unlocked in the specified collection. + +--- + +#### `List` player.teamMembers() + +Returns an array, each entry being a table with `name`, `uuid`, `entity`, `healthPercentage` and `energyPercentage` diff --git a/source/game/StarPlayer.cpp b/source/game/StarPlayer.cpp index 8ee6d7a..15890bb 100644 --- a/source/game/StarPlayer.cpp +++ b/source/game/StarPlayer.cpp @@ -35,6 +35,8 @@ #include "StarInspectionTool.hpp" #include "StarUtilityLuaBindings.hpp" #include "StarCelestialLuaBindings.hpp" +#include "StarUniverseClient.hpp" +#include "StarTeamClient.hpp" namespace Star { @@ -2072,6 +2074,20 @@ Vec2F Player::nametagOrigin() const { void Player::updateIdentity() { m_identityUpdated = true; m_humanoid->setIdentity(m_identity); } +JsonArray Player::teamMembers() { + JsonArray jarray; + for (auto member : m_client->teamClient()->members()) { + jarray.push_back(JsonObject{ + {"name", member.name}, + {"uuid", member.uuid.hex()}, + {"entity", member.entity}, + {"healthPercentage", member.healthPercentage}, + {"energyPercentage", member.energyPercentage} + }); + } + return jarray; +} + void Player::setBodyDirectives(String const& directives) { m_identity.bodyDirectives = directives; updateIdentity(); } diff --git a/source/game/StarPlayer.hpp b/source/game/StarPlayer.hpp index f6e32e0..fe97fce 100644 --- a/source/game/StarPlayer.hpp +++ b/source/game/StarPlayer.hpp @@ -316,6 +316,8 @@ public: void updateIdentity(); + JsonArray teamMembers(); + void setBodyDirectives(String const& directives); void setEmoteDirectives(String const& directives); diff --git a/source/game/scripting/StarPlayerLuaBindings.cpp b/source/game/scripting/StarPlayerLuaBindings.cpp index 7952f30..4343531 100644 --- a/source/game/scripting/StarPlayerLuaBindings.cpp +++ b/source/game/scripting/StarPlayerLuaBindings.cpp @@ -27,6 +27,8 @@ LuaCallbacks LuaBindings::makePlayerCallbacks(Player* player) { } }); + callbacks.registerCallback("teamMembers", [player]() { return player->teamMembers(); }); + callbacks.registerCallback( "humanoidIdentity", [player]() { return player->humanoid()->identity().toJson(); }); callbacks.registerCallback("setHumanoidIdentity", [player](Json const& id) { player->setIdentity(HumanoidIdentity(id)); }); From 99f78c39121178d5b5f444467836e8058ab68f54 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Mon, 21 Oct 2024 16:21:53 +1100 Subject: [PATCH 042/181] add player.trackedQuest --- source/game/scripting/StarPlayerLuaBindings.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/game/scripting/StarPlayerLuaBindings.cpp b/source/game/scripting/StarPlayerLuaBindings.cpp index 7952f30..15ad1dd 100644 --- a/source/game/scripting/StarPlayerLuaBindings.cpp +++ b/source/game/scripting/StarPlayerLuaBindings.cpp @@ -484,6 +484,10 @@ LuaCallbacks LuaBindings::makePlayerCallbacks(Player* player) { return player->questManager()->hasCompleted(questId); }); + callbacks.registerCallback("trackedQuest", [player]() { + return player->questManager()->trackedQuest(); + }); + callbacks.registerCallback("setTrackedQuest", [player](Maybe const& questId) { return player->questManager()->setAsTracked(questId); }); From e3aa302a8c86d7d33afd2ae13a2bdacee141d2bf Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Mon, 21 Oct 2024 16:49:21 +1100 Subject: [PATCH 043/181] Move teamMembers impl to Lua bindings avoiding including UniverseClient.hpp and TeamClient.hpp in StarPlayer --- source/game/StarPlayer.cpp | 20 ++++--------------- source/game/StarPlayer.hpp | 3 +-- .../game/scripting/StarPlayerLuaBindings.cpp | 16 ++++++++++++++- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/source/game/StarPlayer.cpp b/source/game/StarPlayer.cpp index 15890bb..2f89ff3 100644 --- a/source/game/StarPlayer.cpp +++ b/source/game/StarPlayer.cpp @@ -35,8 +35,6 @@ #include "StarInspectionTool.hpp" #include "StarUtilityLuaBindings.hpp" #include "StarCelestialLuaBindings.hpp" -#include "StarUniverseClient.hpp" -#include "StarTeamClient.hpp" namespace Star { @@ -295,6 +293,10 @@ void Player::setUniverseClient(UniverseClient* client) { m_questManager->setUniverseClient(client); } +UniverseClient* Player::universeClient() const { + return m_client; +} + EntityType Player::entityType() const { return EntityType::Player; } @@ -2074,20 +2076,6 @@ Vec2F Player::nametagOrigin() const { void Player::updateIdentity() { m_identityUpdated = true; m_humanoid->setIdentity(m_identity); } -JsonArray Player::teamMembers() { - JsonArray jarray; - for (auto member : m_client->teamClient()->members()) { - jarray.push_back(JsonObject{ - {"name", member.name}, - {"uuid", member.uuid.hex()}, - {"entity", member.entity}, - {"healthPercentage", member.healthPercentage}, - {"energyPercentage", member.energyPercentage} - }); - } - return jarray; -} - void Player::setBodyDirectives(String const& directives) { m_identity.bodyDirectives = directives; updateIdentity(); } diff --git a/source/game/StarPlayer.hpp b/source/game/StarPlayer.hpp index fe97fce..1a6a5c2 100644 --- a/source/game/StarPlayer.hpp +++ b/source/game/StarPlayer.hpp @@ -88,6 +88,7 @@ public: void setStatistics(StatisticsPtr statistics); void setUniverseClient(UniverseClient* universeClient); + UniverseClient* universeClient() const; QuestManagerPtr questManager() const; @@ -316,8 +317,6 @@ public: void updateIdentity(); - JsonArray teamMembers(); - void setBodyDirectives(String const& directives); void setEmoteDirectives(String const& directives); diff --git a/source/game/scripting/StarPlayerLuaBindings.cpp b/source/game/scripting/StarPlayerLuaBindings.cpp index 4343531..b0b44a8 100644 --- a/source/game/scripting/StarPlayerLuaBindings.cpp +++ b/source/game/scripting/StarPlayerLuaBindings.cpp @@ -11,6 +11,8 @@ #include "StarStatistics.hpp" #include "StarPlayerUniverseMap.hpp" #include "StarJsonExtra.hpp" +#include "StarUniverseClient.hpp" +#include "StarTeamClient.hpp" namespace Star { @@ -27,7 +29,19 @@ LuaCallbacks LuaBindings::makePlayerCallbacks(Player* player) { } }); - callbacks.registerCallback("teamMembers", [player]() { return player->teamMembers(); }); + callbacks.registerCallback("teamMembers", [player]() -> Maybe { + if (auto client = player->universeClient()) { + return client->teamClient()->members().transformed([](TeamClient::Member& member) -> Json { + return JsonObject{ + {"name", member.name}, + {"uuid", member.uuid.hex()}, + {"entity", member.entity}, + {"healthPercentage", member.healthPercentage}, + {"energyPercentage", member.energyPercentage}}; + }); + } + return {}; + }); callbacks.registerCallback( "humanoidIdentity", [player]() { return player->humanoid()->identity().toJson(); }); callbacks.registerCallback("setHumanoidIdentity", [player](Json const& id) { player->setIdentity(HumanoidIdentity(id)); }); From 5c669f4b3a772fee96c8e4e10ecc6d32984e890a Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Mon, 21 Oct 2024 16:54:10 +1100 Subject: [PATCH 044/181] change to trackedQuestId, add currentQuestId --- source/game/StarQuestManager.cpp | 8 ++++++++ source/game/StarQuestManager.hpp | 2 ++ source/game/scripting/StarPlayerLuaBindings.cpp | 8 ++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/source/game/StarQuestManager.cpp b/source/game/StarQuestManager.cpp index 876f0b8..df8a19a 100644 --- a/source/game/StarQuestManager.cpp +++ b/source/game/StarQuestManager.cpp @@ -273,6 +273,10 @@ List QuestManager::listFailedQuests() const { return result; } +Maybe QuestManager::currentQuestId() const { + return m_trackedQuestId; +} + Maybe QuestManager::currentQuest() const { auto questId = m_onWorldQuestId.orMaybe(m_trackedQuestId); if (questId && isActive(*questId)) { @@ -283,6 +287,10 @@ Maybe QuestManager::currentQuest() const { return {}; } +Maybe QuestManager::trackedQuestId() const { + return m_trackedQuestId; +} + Maybe QuestManager::trackedQuest() const { if (m_trackedQuestId && isActive(*m_trackedQuestId)) { auto current = getQuest(*m_trackedQuestId); diff --git a/source/game/StarQuestManager.hpp b/source/game/StarQuestManager.hpp index 3d7ee22..549f13b 100644 --- a/source/game/StarQuestManager.hpp +++ b/source/game/StarQuestManager.hpp @@ -52,7 +52,9 @@ public: List listCompletedQuests() const; List listFailedQuests() const; + Maybe currentQuestId() const; Maybe currentQuest() const; + Maybe trackedQuestId() const; Maybe trackedQuest() const; Maybe getQuestIndicator(EntityPtr const& entity) const; diff --git a/source/game/scripting/StarPlayerLuaBindings.cpp b/source/game/scripting/StarPlayerLuaBindings.cpp index 15ad1dd..ea902ab 100644 --- a/source/game/scripting/StarPlayerLuaBindings.cpp +++ b/source/game/scripting/StarPlayerLuaBindings.cpp @@ -484,8 +484,8 @@ LuaCallbacks LuaBindings::makePlayerCallbacks(Player* player) { return player->questManager()->hasCompleted(questId); }); - callbacks.registerCallback("trackedQuest", [player]() { - return player->questManager()->trackedQuest(); + callbacks.registerCallback("trackedQuestId", [player]() { + return player->questManager()->trackedQuestId(); }); callbacks.registerCallback("setTrackedQuest", [player](Maybe const& questId) { @@ -496,6 +496,10 @@ LuaCallbacks LuaBindings::makePlayerCallbacks(Player* player) { return player->questManager()->canTurnIn(questId); }); + callbacks.registerCallback("currentQuestId", [player]() { + return player->questManager()->currentQuestId(); + }); + callbacks.registerCallback("currentQuest", [player]() -> Json { auto maybeQuest = player->questManager()->currentQuest(); if (maybeQuest) { From 2796e8ed1035c12a6645c3130b1c43d4e4c68784 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Mon, 21 Oct 2024 16:55:31 +1100 Subject: [PATCH 045/181] Update StarPlayerLuaBindings.cpp --- source/game/scripting/StarPlayerLuaBindings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/game/scripting/StarPlayerLuaBindings.cpp b/source/game/scripting/StarPlayerLuaBindings.cpp index b0b44a8..f8e1f2e 100644 --- a/source/game/scripting/StarPlayerLuaBindings.cpp +++ b/source/game/scripting/StarPlayerLuaBindings.cpp @@ -31,7 +31,7 @@ LuaCallbacks LuaBindings::makePlayerCallbacks(Player* player) { callbacks.registerCallback("teamMembers", [player]() -> Maybe { if (auto client = player->universeClient()) { - return client->teamClient()->members().transformed([](TeamClient::Member& member) -> Json { + return client->teamClient()->members().transformed([](TeamClient::Member const& member) -> Json { return JsonObject{ {"name", member.name}, {"uuid", member.uuid.hex()}, From 73e9ab3b8e310b1fed87297a1876048d22a122ec Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Mon, 21 Oct 2024 20:05:07 +1100 Subject: [PATCH 046/181] player.callQuest --- source/game/StarQuestManager.cpp | 5 ++++- source/game/StarQuests.cpp | 15 +++++++++++++++ source/game/StarQuests.hpp | 1 + source/game/scripting/StarPlayerLuaBindings.cpp | 13 ++++++++++--- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/source/game/StarQuestManager.cpp b/source/game/StarQuestManager.cpp index df8a19a..ee2c82b 100644 --- a/source/game/StarQuestManager.cpp +++ b/source/game/StarQuestManager.cpp @@ -144,7 +144,10 @@ StringMap QuestManager::serverQuests() const { } QuestPtr QuestManager::getQuest(String const& questId) const { - return m_quests.get(questId); + if (auto quest = m_quests.ptr(questId)) + return *quest; + + return {}; } bool QuestManager::hasQuest(String const& questId) const { diff --git a/source/game/StarQuests.cpp b/source/game/StarQuests.cpp index 6e1dba7..d0d9d99 100644 --- a/source/game/StarQuests.cpp +++ b/source/game/StarQuests.cpp @@ -216,6 +216,13 @@ Maybe Quest::receiveMessage(String const& message, bool localMessage, Json return m_scriptComponent.handleMessage(message, localMessage, args); } + +Maybe Quest::callScript(String const& func, LuaVariadic const& args) { + if (!m_inited) + return {}; + return m_scriptComponent.invoke(func, args); +} + void Quest::update(float dt) { if (!m_inited) return; @@ -599,12 +606,20 @@ void Quest::uninitScript() { LuaCallbacks Quest::makeQuestCallbacks(Player* player) { LuaCallbacks callbacks; + callbacks.registerCallback("context", [this]() { m_scriptComponent.context(); }); + callbacks.registerCallback("state", [this]() { return QuestStateNames.getRight(state()); }); callbacks.registerCallback("complete", [this](Maybe followup) { complete(followup); }); callbacks.registerCallback("fail", [this]() { fail(); }); + callbacks.registerCallback("abandon", [this]() { abandon(); }); + + callbacks.registerCallback("decline", [this]() { declineOffer(); }); + + callbacks.registerCallback("cancel", [this]() { cancelOffer(); }); + callbacks.registerCallback("setCanTurnIn", [this](bool value) { this->m_canTurnIn = value; }); callbacks.registerCallback("questId", [this]() { return questId(); }); diff --git a/source/game/StarQuests.hpp b/source/game/StarQuests.hpp index fc35f2b..6a4b128 100644 --- a/source/game/StarQuests.hpp +++ b/source/game/StarQuests.hpp @@ -45,6 +45,7 @@ public: void uninit(); Maybe receiveMessage(String const& message, bool localMessage, JsonArray const& args = {}); + Maybe callScript(String const& func, LuaVariadic const& args); void update(float dt); void offer(); diff --git a/source/game/scripting/StarPlayerLuaBindings.cpp b/source/game/scripting/StarPlayerLuaBindings.cpp index bf14c2c..7546567 100644 --- a/source/game/scripting/StarPlayerLuaBindings.cpp +++ b/source/game/scripting/StarPlayerLuaBindings.cpp @@ -478,10 +478,17 @@ LuaCallbacks LuaBindings::makePlayerCallbacks(Player* player) { }); callbacks.registerCallback("quest", [player](String const& questId) -> Json { - if (!player->questManager()->hasQuest(questId)) - return {}; + if (auto quest = player->questManager()->getQuest(questId)) + return quest->diskStore(); - return player->questManager()->getQuest(questId)->diskStore(); + return {}; + }); + + callbacks.registerCallback("callQuest", [player](String const& questId, String const& func, LuaVariadic const& args) -> Maybe { + if (auto quest = player->questManager()->getQuest(questId)) + return quest->callScript(func, args); + + return {}; }); callbacks.registerCallback("hasQuest", [player](String const& questId) { From 15d116b7eac53f1d0526aa80ab9d59b89661b128 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Wed, 23 Oct 2024 15:05:00 +1100 Subject: [PATCH 047/181] fix broken minidumping --- source/core/StarSignalHandler_windows.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/source/core/StarSignalHandler_windows.cpp b/source/core/StarSignalHandler_windows.cpp index 13a36ac..2b27467 100644 --- a/source/core/StarSignalHandler_windows.cpp +++ b/source/core/StarSignalHandler_windows.cpp @@ -123,14 +123,15 @@ struct SignalHandlerImpl { static LONG CALLBACK vectoredExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) { auto thread = CreateThread(NULL, 0, writeMiniDump, (void*)ExceptionInfo, 0, NULL); + LONG result = EXCEPTION_CONTINUE_SEARCH; if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { handleFatalError("Access violation detected", ExceptionInfo); - return EXCEPTION_CONTINUE_EXECUTION; + result = EXCEPTION_CONTINUE_EXECUTION; } if ((ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION) || (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION)) { handleFatalError("Illegal instruction encountered", ExceptionInfo); - return EXCEPTION_CONTINUE_EXECUTION; + result = EXCEPTION_CONTINUE_EXECUTION; } if ((ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_FLT_DENORMAL_OPERAND) @@ -143,17 +144,17 @@ struct SignalHandlerImpl { ) { handleFatalError("Floating point exception", ExceptionInfo); - return EXCEPTION_CONTINUE_EXECUTION; + result = EXCEPTION_CONTINUE_EXECUTION; } if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO) { handleFatalError("Division by zero", ExceptionInfo); - return EXCEPTION_CONTINUE_EXECUTION; + result = EXCEPTION_CONTINUE_EXECUTION; } if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_INT_OVERFLOW) { handleFatalError("Integer overflow", ExceptionInfo); - return EXCEPTION_CONTINUE_EXECUTION; + result = EXCEPTION_CONTINUE_EXECUTION; } if ((ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_DATATYPE_MISALIGNMENT) @@ -163,13 +164,13 @@ struct SignalHandlerImpl { || (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_INVALID_DISPOSITION) || (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_INVALID_HANDLE)) { handleFatalError("Error occured", ExceptionInfo); - return EXCEPTION_CONTINUE_EXECUTION; + result = EXCEPTION_CONTINUE_EXECUTION; } if (thread != NULL) { WaitForSingleObject(thread, 10000); CloseHandle(thread); } - return EXCEPTION_CONTINUE_SEARCH; + return result; } static BOOL WINAPI consoleCtrlHandler(DWORD) { From 20c79e32f8aed496f5c9dad433cacdca18aed4cf Mon Sep 17 00:00:00 2001 From: Charlotte Koch Date: Thu, 24 Oct 2024 15:42:26 -0700 Subject: [PATCH 048/181] Add preliminary support for NetBSD --- source/CMakeLists.txt | 8 ++++++++ source/core/StarThread_unix.cpp | 2 ++ 2 files changed, 10 insertions(+) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index d13d59d..59fa0a6 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -80,6 +80,8 @@ if(NOT DEFINED STAR_SYSTEM) set(STAR_SYSTEM "linux") elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") set(STAR_SYSTEM "freebsd") + elseif(${CMAKE_SYSTEM_NAME} STREQUAL "NetBSD") + set(STAR_SYSTEM "netbsd") elseif(UNIX) set(STAR_SYSTEM "unix") else() @@ -208,6 +210,8 @@ elseif(STAR_SYSTEM STREQUAL "linux") set_flag(STAR_SYSTEM_LINUX) elseif(STAR_SYSTEM STREQUAL "freebsd") set_flag(STAR_SYSTEM_FREEBSD) +elseif(STAR_SYSTEM STREQUAL "netbsd") + set_flag(STAR_SYSTEM_NETBSD) endif() if(STAR_SYSTEM_FAMILY STREQUAL "windows") @@ -445,6 +449,10 @@ elseif(STAR_SYSTEM_FREEBSD) set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} -lpthread -lrt") set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -lpthread -lrt") +elseif(STAR_SYSTEM_NETBSD) + set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} -lpthread -lrt -lexecinfo") + set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -lpthread -lrt -lexecinfo") + endif() # Find all required external libraries, based on build settings... diff --git a/source/core/StarThread_unix.cpp b/source/core/StarThread_unix.cpp index 7385ae2..fe82ea3 100644 --- a/source/core/StarThread_unix.cpp +++ b/source/core/StarThread_unix.cpp @@ -78,6 +78,8 @@ struct ThreadImpl { #ifdef STAR_SYSTEM_FREEBSD pthread_set_name_np(pthread, tname); +#elif defined(STAR_SYSTEM_NETBSD) + pthread_setname_np(pthread, "%s", tname); #elif not defined STAR_SYSTEM_MACOS pthread_setname_np(pthread, tname); #endif From c2b9f5ac078379090f64f9d8840960555c79e22d Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Fri, 25 Oct 2024 11:19:27 +1100 Subject: [PATCH 049/181] Only create a dump on stack overflow --- source/core/StarSignalHandler_windows.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/core/StarSignalHandler_windows.cpp b/source/core/StarSignalHandler_windows.cpp index 2b27467..676734c 100644 --- a/source/core/StarSignalHandler_windows.cpp +++ b/source/core/StarSignalHandler_windows.cpp @@ -122,8 +122,11 @@ struct SignalHandlerImpl { } static LONG CALLBACK vectoredExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) { - auto thread = CreateThread(NULL, 0, writeMiniDump, (void*)ExceptionInfo, 0, NULL); + HANDLE thread = NULL; LONG result = EXCEPTION_CONTINUE_SEARCH; + if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) { + thread = CreateThread(NULL, 0, writeMiniDump, (void*)ExceptionInfo, 0, NULL); + } if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { handleFatalError("Access violation detected", ExceptionInfo); result = EXCEPTION_CONTINUE_EXECUTION; From 42a648ecc10659676297851238516e14ec1b96d2 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Fri, 25 Oct 2024 11:59:33 +1100 Subject: [PATCH 050/181] Update StarPlayerLuaBindings.cpp --- source/game/scripting/StarPlayerLuaBindings.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/game/scripting/StarPlayerLuaBindings.cpp b/source/game/scripting/StarPlayerLuaBindings.cpp index 7546567..4d3b316 100644 --- a/source/game/scripting/StarPlayerLuaBindings.cpp +++ b/source/game/scripting/StarPlayerLuaBindings.cpp @@ -484,6 +484,13 @@ LuaCallbacks LuaBindings::makePlayerCallbacks(Player* player) { return {}; }); + callbacks.registerCallback("questState", [player](String const& questId) -> Maybe { + if (auto quest = player->questManager()->getQuest(questId)) + return QuestStateNames.getRight(quest->state()); + + return {}; + }); + callbacks.registerCallback("callQuest", [player](String const& questId, String const& func, LuaVariadic const& args) -> Maybe { if (auto quest = player->questManager()->getQuest(questId)) return quest->callScript(func, args); From beea448827a6d79067e58b19f820a67e2a044f98 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sat, 26 Oct 2024 10:46:46 +1100 Subject: [PATCH 051/181] fix WorldClient::m_inWorld being false during during player init this was breaking a few new checks fixes #136 --- source/game/StarWorldClient.cpp | 36 ++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/source/game/StarWorldClient.cpp b/source/game/StarWorldClient.cpp index d3e5c0c..8d6cb82 100644 --- a/source/game/StarWorldClient.cpp +++ b/source/game/StarWorldClient.cpp @@ -485,7 +485,7 @@ void WorldClient::render(WorldRenderData& renderData, unsigned bufferTiles) { const List* directives = nullptr; if (auto& worldTemplate = m_worldTemplate) { if (const auto& parameters = worldTemplate->worldParameters()) - if (auto& globalDirectives = m_worldTemplate->worldParameters()->globalDirectives) + if (auto& globalDirectives = parameters->globalDirectives) directives = &globalDirectives.get(); } m_entityMap->forAllEntities([&](EntityPtr const& entity) { @@ -1541,7 +1541,7 @@ void WorldClient::handleDamageNotifications() { const List* directives = nullptr; if (auto& worldTemplate = m_worldTemplate) { if (const auto& parameters = worldTemplate->worldParameters()) - if (auto& globalDirectives = m_worldTemplate->worldParameters()->globalDirectives) + if (auto& globalDirectives = parameters->globalDirectives) directives = &globalDirectives.get(); } if (directives) { @@ -1775,20 +1775,6 @@ void WorldClient::initWorld(WorldStartPacket const& startPacket) { setupForceRegions(); - if (!m_mainPlayer->isDead()) { - m_mainPlayer->init(this, m_entityMap->reserveEntityId(), EntityMode::Master); - m_entityMap->addEntity(m_mainPlayer); - } - m_mainPlayer->moveTo(startPacket.playerStart); - if (m_worldTemplate->worldParameters()) - m_mainPlayer->overrideTech(m_worldTemplate->worldParameters()->overrideTech); - else - m_mainPlayer->overrideTech({}); - - // Auto reposition the client window on the player when the main player - // changes position. - centerClientWindowOnPlayer(); - m_sky = make_shared(); m_sky->readUpdate(startPacket.skyData, m_clientState.netCompatibilityRules()); @@ -1803,6 +1789,20 @@ void WorldClient::initWorld(WorldStartPacket const& startPacket) { m_lightIntensityCalculator.setParameters(assets->json("/lighting.config:intensity")); m_inWorld = true; + + if (!m_mainPlayer->isDead()) { + m_mainPlayer->init(this, m_entityMap->reserveEntityId(), EntityMode::Master); + m_entityMap->addEntity(m_mainPlayer); + } + m_mainPlayer->moveTo(startPacket.playerStart); + if (const auto& parameters = m_worldTemplate->worldParameters()) + m_mainPlayer->overrideTech(parameters->overrideTech); + else + m_mainPlayer->overrideTech({}); + + // Auto reposition the client window on the player when the main player + // changes position. + centerClientWindowOnPlayer(); } void WorldClient::clearWorld() { @@ -2113,8 +2113,8 @@ bool WorldClient::isUnderground(Vec2F const& pos) const { } bool WorldClient::disableDeathDrops() const { - if (m_worldTemplate->worldParameters()) - return m_worldTemplate->worldParameters()->disableDeathDrops; + if (const auto& parameters = m_worldTemplate->worldParameters()) + return parameters->disableDeathDrops; return false; } From e065981ce2490cca77a3785bba95715aa6eb3ac7 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sun, 27 Oct 2024 05:44:33 +1100 Subject: [PATCH 052/181] Update StarWorldClient.cpp --- source/game/StarWorldClient.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/game/StarWorldClient.cpp b/source/game/StarWorldClient.cpp index 8d6cb82..6f0f2af 100644 --- a/source/game/StarWorldClient.cpp +++ b/source/game/StarWorldClient.cpp @@ -1327,7 +1327,7 @@ void WorldClient::addEntity(EntityPtr const& entity, EntityId entityId) { } else { auto entityFactory = Root::singleton().entityFactory(); auto netRules = m_clientState.netCompatibilityRules(); - m_outgoingPackets.append(make_shared(entity->entityType(), entityFactory->netStoreEntity(entity), entity->writeNetState(0, netRules).first)); + m_outgoingPackets.append(make_shared(entity->entityType(), entityFactory->netStoreEntity(entity, netRules), entity->writeNetState(0, netRules).first)); } } @@ -1873,7 +1873,7 @@ void WorldClient::notifyEntityCreate(EntityPtr const& entity) { auto firstNetState = entity->writeNetState(0, netRules); m_masterEntitiesNetVersion[entity->entityId()] = firstNetState.second; m_outgoingPackets.append(make_shared(entity->entityType(), - Root::singleton().entityFactory()->netStoreEntity(entity), std::move(firstNetState.first), entity->entityId())); + Root::singleton().entityFactory()->netStoreEntity(entity, netRules), std::move(firstNetState.first), entity->entityId())); } } From 391f148f11c90415f64b9cadc4ff88855cd5f432 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Mon, 28 Oct 2024 15:04:46 +1100 Subject: [PATCH 053/181] Update StarItemTooltip.cpp --- source/frontend/StarItemTooltip.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/frontend/StarItemTooltip.cpp b/source/frontend/StarItemTooltip.cpp index 7cec755..492672b 100644 --- a/source/frontend/StarItemTooltip.cpp +++ b/source/frontend/StarItemTooltip.cpp @@ -205,7 +205,7 @@ void ItemTooltipBuilder::describePersistentEffect( auto listItem = container->addItem(); listItem->fetchChild("statusImage") ->setImage(statsConfig.get(valueModifier->statName).getString("icon")); - listItem->setLabel("statusLabel", strf("{}{}", valueModifier->value < 0 ? "-" : "", valueModifier->value)); + listItem->setLabel("statusLabel", strf("{}{:.2f}", valueModifier->value < 0 ? "-" : "", valueModifier->value)); } } else if (auto effectiveMultiplier = modifierEffect->ptr()) { if (statsConfig.contains(effectiveMultiplier->statName)) { From cc5fbb0087518a2f4ab9e86f5b2cff2d3b0ed3fb Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 29 Oct 2024 20:12:58 +1100 Subject: [PATCH 054/181] fix broken status.primaryDirectives why did it even compile before. what the fuck! --- source/game/scripting/StarStatusControllerLuaBindings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/game/scripting/StarStatusControllerLuaBindings.cpp b/source/game/scripting/StarStatusControllerLuaBindings.cpp index 819c517..7edcb6f 100644 --- a/source/game/scripting/StarStatusControllerLuaBindings.cpp +++ b/source/game/scripting/StarStatusControllerLuaBindings.cpp @@ -81,7 +81,7 @@ LuaCallbacks LuaBindings::makeStatusControllerCallbacks(StatusController* statCo callbacks.registerCallbackWithSignature("uniqueStatusEffectActive", bind(&StatusControllerCallbacks::uniqueStatusEffectActive, statController, _1)); - callbacks.registerCallbackWithSignature("primaryDirectives", bind(&StatusController::primaryDirectives, statController)); + callbacks.registerCallbackWithSignature("primaryDirectives", bind(&StatusController::primaryDirectives, statController)); callbacks.registerCallback("setPrimaryDirectives", [statController](Maybe const& directives) { statController->setPrimaryDirectives(directives.value()); }); callbacks.registerCallbackWithSignature("applySelfDamageRequest", bind(&StatusController::applySelfDamageRequest, statController, _1)); From 6423dead1f89ef89f11bb018aa471f3bbb199f22 Mon Sep 17 00:00:00 2001 From: SilverSokolova <80606782+SilverSokolova@users.noreply.github.com> Date: Tue, 29 Oct 2024 21:38:37 -0500 Subject: [PATCH 055/181] Interface docs --- doc/lua/openstarbound.md | 57 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/doc/lua/openstarbound.md b/doc/lua/openstarbound.md index b5ceef0..d520705 100644 --- a/doc/lua/openstarbound.md +++ b/doc/lua/openstarbound.md @@ -114,6 +114,63 @@ Sets a configuration value in `/storage/starbound.config` by path. Returns all recipes. +--- +# Interface + +The interface table contains bindings which allow scripts to display a message at the bottom of the screen, among other things. + +#### `void` interface.queueMessage(`String` message, [`float` cooldown, [`float` springState]]) + +Queues a message popup at the bottom of the screen with an optional **cooldown** and **springState**. + +#### `void` interface.setHudVisible(`bool` visible) + +Sets the HUD's visibility. + +#### `bool` interface.hudVisible() + +Returns the HUD's visibility. + +#### `PaneId` interface.bindRegisteredPane(`string` paneName) +Binds a registered pane (defined in `/source/frontend/StarMainInterfaceTypes`) to a Lua value, which can then call functions on that pane. +
Panes +EscapeDialog
+Inventory
+Codex
+Cockpit
+Tech
+Songbook
+Ai
+Popup
+Confirmation
+JoinRequest
+Options
+QuestLog
+ActionBar
+TeamBar
+StatusPane
+Chat
+WireInterface
+PlanetText
+RadioMessagePopup
+CraftingPlain
+QuestTracker
+MmUpgrade
+Collections
+
+ +#### `void` interface.displayRegisteredPane(`string` paneName) +Displays a registered pane. + + +#### `?` interface.bindCanvas() +TODO + + +#### `int` interface.scale() +Returns the scale used for interfaces. + + --- # Player From e1dea58e809bb2440b81a1771c6df916e50dda1a Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 5 Nov 2024 09:44:46 +1100 Subject: [PATCH 056/181] questPortrait callback --- source/game/StarQuestManager.cpp | 5 +--- .../game/scripting/StarPlayerLuaBindings.cpp | 28 +++++++++++-------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/source/game/StarQuestManager.cpp b/source/game/StarQuestManager.cpp index ee2c82b..df8a19a 100644 --- a/source/game/StarQuestManager.cpp +++ b/source/game/StarQuestManager.cpp @@ -144,10 +144,7 @@ StringMap QuestManager::serverQuests() const { } QuestPtr QuestManager::getQuest(String const& questId) const { - if (auto quest = m_quests.ptr(questId)) - return *quest; - - return {}; + return m_quests.get(questId); } bool QuestManager::hasQuest(String const& questId) const { diff --git a/source/game/scripting/StarPlayerLuaBindings.cpp b/source/game/scripting/StarPlayerLuaBindings.cpp index 4d3b316..5af86d0 100644 --- a/source/game/scripting/StarPlayerLuaBindings.cpp +++ b/source/game/scripting/StarPlayerLuaBindings.cpp @@ -478,24 +478,28 @@ LuaCallbacks LuaBindings::makePlayerCallbacks(Player* player) { }); callbacks.registerCallback("quest", [player](String const& questId) -> Json { - if (auto quest = player->questManager()->getQuest(questId)) - return quest->diskStore(); - - return {}; + if (!player->questManager()->hasQuest(questId)) + return {}; + return player->questManager()->getQuest(questId)->diskStore(); }); - callbacks.registerCallback("questState", [player](String const& questId) -> Maybe { - if (auto quest = player->questManager()->getQuest(questId)) - return QuestStateNames.getRight(quest->state()); + callbacks.registerCallback("questPortrait", [player](String const& questId, String const& portraitName) -> Maybe> { + if (!player->questManager()->hasQuest(questId)) + return {}; + return player->questManager()->getQuest(questId)->portrait(portraitName); + }); - return {}; + + callbacks.registerCallback("questState", [player](String const& questId) -> Maybe { + if (!player->questManager()->hasQuest(questId)) + return {}; + return QuestStateNames.getRight(player->questManager()->getQuest(questId)->state()); }); callbacks.registerCallback("callQuest", [player](String const& questId, String const& func, LuaVariadic const& args) -> Maybe { - if (auto quest = player->questManager()->getQuest(questId)) - return quest->callScript(func, args); - - return {}; + if (!player->questManager()->hasQuest(questId)) + return {}; + return player->questManager()->getQuest(questId)->callScript(func, args); }); callbacks.registerCallback("hasQuest", [player](String const& questId) { From 515d71409c4b65c159ac6c0e815657f3ece56cb2 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 5 Nov 2024 10:23:03 +1100 Subject: [PATCH 057/181] support for an absurd hacky trick used by FD: appending to the frame ID via the directives parameter wtf :sob: --- source/core/StarDirectives.cpp | 9 ++++ source/core/StarDirectives.hpp | 1 + source/game/StarHumanoid.cpp | 80 +++++++++++++++++++--------------- 3 files changed, 56 insertions(+), 34 deletions(-) diff --git a/source/core/StarDirectives.cpp b/source/core/StarDirectives.cpp index ea18bc9..b72e8ee 100644 --- a/source/core/StarDirectives.cpp +++ b/source/core/StarDirectives.cpp @@ -156,6 +156,15 @@ void Directives::parse(String&& directives) { } } +StringView Directives::prefix() const { + if (!m_shared) + return ""; + else if (m_shared->empty()) + return m_shared->string; + else + return StringView(m_shared->string).substr(0, m_shared->entries.begin()->begin); +} + String Directives::string() const { if (!m_shared) return ""; diff --git a/source/core/StarDirectives.hpp b/source/core/StarDirectives.hpp index 9290649..d83a3e8 100644 --- a/source/core/StarDirectives.hpp +++ b/source/core/StarDirectives.hpp @@ -55,6 +55,7 @@ public: void loadOperations() const; void parse(String&& directives); + StringView prefix() const; String string() const; String const* stringPtr() const; String buildString() const; diff --git a/source/game/StarHumanoid.cpp b/source/game/StarHumanoid.cpp index d140881..6dfe8e3 100644 --- a/source/game/StarHumanoid.cpp +++ b/source/game/StarHumanoid.cpp @@ -544,7 +544,7 @@ List Humanoid::render(bool withItems, bool withRotationAndScale) { }; auto backArmDrawable = [&](String const& frameSet, Directives const& directives) -> Drawable { - String image = strf("{}:{}", frameSet, backHand.backFrame); + String image = strf("{}:{}{}", frameSet, backHand.backFrame, directives.prefix()); Drawable backArm = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, backArmFrameOffset); backArm.imagePart().addDirectives(directives, true); backArm.rotate(backHand.angle, backArmFrameOffset + m_backArmRotationCenter + m_backArmOffset); @@ -553,15 +553,16 @@ List Humanoid::render(bool withItems, bool withRotationAndScale) { if (!m_backArmorFrameset.empty()) { auto frameGroup = frameBase(m_state); + auto prefix = m_backArmorDirectives.prefix(); if (m_movingBackwards && (m_state == State::Run)) frameGroup = "runbackwards"; String image; if (dance.isValid() && danceStep->bodyFrame) - image = strf("{}:{}", m_backArmorFrameset, *danceStep->bodyFrame); + image = strf("{}:{}{}", m_backArmorFrameset, *danceStep->bodyFrame, prefix); else if (m_state == Idle) - image = strf("{}:{}", m_backArmorFrameset, m_identity.personality.idle); + image = strf("{}:{}{}", m_backArmorFrameset, m_identity.personality.idle, prefix); else - image = strf("{}:{}.{}", m_backArmorFrameset, frameGroup, bodyStateSeq); + image = strf("{}:{}.{}{}", m_backArmorFrameset, frameGroup, bodyStateSeq, prefix); auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, Vec2F()); drawable.imagePart().addDirectives(getBackDirectives(), true); @@ -588,16 +589,18 @@ List Humanoid::render(bool withItems, bool withRotationAndScale) { if (!m_backArmFrameset.empty() && !m_bodyHidden) { String image; Vec2F position; + auto bodyDirectives = getBodyDirectives(); + auto prefix = bodyDirectives.prefix(); if (dance.isValid() && danceStep->backArmFrame) { - image = strf("{}:{}", m_backArmFrameset, *danceStep->backArmFrame); + image = strf("{}:{}{}", m_backArmFrameset, *danceStep->backArmFrame, prefix); position = danceStep->backArmOffset / TilePixels; } else if (m_state == Idle) { - image = strf("{}:{}", m_backArmFrameset, m_identity.personality.armIdle); + image = strf("{}:{}{}", m_backArmFrameset, m_identity.personality.armIdle, prefix); position = m_identity.personality.armOffset / TilePixels; } else - image = strf("{}:{}.{}", m_backArmFrameset, frameBase(m_state), armStateSeq); + image = strf("{}:{}.{}{}", m_backArmFrameset, frameBase(m_state), armStateSeq, prefix); auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, position); - drawable.imagePart().addDirectives(getBodyDirectives(), true); + drawable.imagePart().addDirectives(bodyDirectives, true); if (dance.isValid()) drawable.rotate(danceStep->backArmRotation); addDrawable(std::move(drawable), m_bodyFullbright); @@ -605,14 +608,15 @@ List Humanoid::render(bool withItems, bool withRotationAndScale) { if (!m_backSleeveFrameset.empty()) { String image; Vec2F position; + auto prefix = m_chestArmorDirectives.prefix(); if (dance.isValid() && danceStep->backArmFrame) { - image = strf("{}:{}", m_backSleeveFrameset, *danceStep->backArmFrame); + image = strf("{}:{}{}", m_backSleeveFrameset, *danceStep->backArmFrame, prefix); position = danceStep->backArmOffset / TilePixels; } else if (m_state == Idle) { - image = strf("{}:{}", m_backSleeveFrameset, m_identity.personality.armIdle); + image = strf("{}:{}{}", m_backSleeveFrameset, m_identity.personality.armIdle, prefix); position = m_identity.personality.armOffset / TilePixels; } else - image = strf("{}:{}.{}", m_backSleeveFrameset, frameBase(m_state), armStateSeq); + image = strf("{}:{}.{}{}", m_backSleeveFrameset, frameBase(m_state), armStateSeq, prefix); auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, position); drawable.imagePart().addDirectives(getChestDirectives(), true); if (dance.isValid()) @@ -645,9 +649,10 @@ List Humanoid::render(bool withItems, bool withRotationAndScale) { } if (!m_emoteFrameset.empty() && !m_bodyHidden) { - String image = strf("{}:{}.{}", m_emoteFrameset, emoteFrameBase(m_emoteState), emoteStateSeq); + auto emoteDirectives = getEmoteDirectives(); + String image = strf("{}:{}.{}{}", m_emoteFrameset, emoteFrameBase(m_emoteState), emoteStateSeq, emoteDirectives.prefix()); auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, headPosition); - drawable.imagePart().addDirectives(getEmoteDirectives(), true); + drawable.imagePart().addDirectives(emoteDirectives, true); addDrawable(std::move(drawable), m_bodyFullbright); } @@ -660,25 +665,28 @@ List Humanoid::render(bool withItems, bool withRotationAndScale) { if (!m_bodyFrameset.empty() && !m_bodyHidden) { String image; + auto bodyDirectives = getBodyDirectives(); + auto prefix = bodyDirectives.prefix(); if (dance.isValid() && danceStep->bodyFrame) - image = strf("{}:{}", m_bodyFrameset, *danceStep->bodyFrame); + image = strf("{}:{}{}", m_bodyFrameset, *danceStep->bodyFrame, prefix); else if (m_state == Idle) - image = strf("{}:{}", m_bodyFrameset, m_identity.personality.idle); + image = strf("{}:{}{}", m_bodyFrameset, m_identity.personality.idle, prefix); else - image = strf("{}:{}.{}", m_bodyFrameset, frameBase(m_state), bodyStateSeq); + image = strf("{}:{}.{}{}", m_bodyFrameset, frameBase(m_state), bodyStateSeq, prefix); auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, {}); - drawable.imagePart().addDirectives(getBodyDirectives(), true); + drawable.imagePart().addDirectives(bodyDirectives, true); addDrawable(std::move(drawable), m_bodyFullbright); } if (!m_legsArmorFrameset.empty()) { String image; + auto prefix = m_legsArmorDirectives.prefix(); if (dance.isValid() && danceStep->bodyFrame) - image = strf("{}:{}", m_legsArmorFrameset, *danceStep->bodyFrame); + image = strf("{}:{}{}", m_legsArmorFrameset, *danceStep->bodyFrame, prefix); else if (m_state == Idle) - image = strf("{}:{}", m_legsArmorFrameset, m_identity.personality.idle); + image = strf("{}:{}{}", m_legsArmorFrameset, m_identity.personality.idle, prefix); else - image = strf("{}:{}.{}", m_legsArmorFrameset, frameBase(m_state), bodyStateSeq); + image = strf("{}:{}.{}{}", m_legsArmorFrameset, frameBase(m_state), bodyStateSeq, prefix); auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, {}); drawable.imagePart().addDirectives(getLegsDirectives(), true); addDrawable(std::move(drawable)); @@ -687,18 +695,19 @@ List Humanoid::render(bool withItems, bool withRotationAndScale) { if (!m_chestArmorFrameset.empty()) { String image; Vec2F position; + auto prefix = m_chestArmorDirectives.prefix(); if (dance.isValid() && danceStep->bodyFrame) - image = strf("{}:{}", m_chestArmorFrameset, *danceStep->bodyFrame); + image = strf("{}:{}{}", m_chestArmorFrameset, *danceStep->bodyFrame, prefix); else if (m_state == Run) - image = strf("{}:run", m_chestArmorFrameset); + image = strf("{}:run{}", m_chestArmorFrameset, prefix); else if (m_state == Idle) - image = strf("{}:{}", m_chestArmorFrameset, m_identity.personality.idle); + image = strf("{}:{}{}", m_chestArmorFrameset, m_identity.personality.idle, prefix); else if (m_state == Duck) - image = strf("{}:duck", m_chestArmorFrameset); + image = strf("{}:duck{}", m_chestArmorFrameset, prefix); else if ((m_state == Swim) || (m_state == SwimIdle)) - image = strf("{}:swim", m_chestArmorFrameset); + image = strf("{}:swim{}", m_chestArmorFrameset, prefix); else - image = strf("{}:chest.1", m_chestArmorFrameset); + image = strf("{}:chest.1{}", m_chestArmorFrameset, prefix); if (m_state != Duck) position[1] += bobYOffset; auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, position); @@ -728,7 +737,7 @@ List Humanoid::render(bool withItems, bool withRotationAndScale) { } auto frontArmDrawable = [&](String const& frameSet, Directives const& directives) -> Drawable { - String image = strf("{}:{}", frameSet, frontHand.frontFrame); + String image = strf("{}:{}{}", frameSet, frontHand.frontFrame, directives.prefix()); Drawable frontArm = Drawable::makeImage(image, 1.0f / TilePixels, true, frontArmFrameOffset); frontArm.imagePart().addDirectives(directives, true); frontArm.rotate(frontHand.angle, frontArmFrameOffset + m_frontArmRotationCenter); @@ -755,16 +764,18 @@ List Humanoid::render(bool withItems, bool withRotationAndScale) { if (!m_frontArmFrameset.empty() && !m_bodyHidden) { String image; Vec2F position; + auto bodyDirectives = getBodyDirectives(); + auto prefix = bodyDirectives.prefix(); if (dance.isValid() && danceStep->frontArmFrame) { - image = strf("{}:{}", m_frontArmFrameset, *danceStep->frontArmFrame); + image = strf("{}:{}{}", m_frontArmFrameset, *danceStep->frontArmFrame, prefix); position = danceStep->frontArmOffset / TilePixels; } else if (m_state == Idle) { - image = strf("{}:{}", m_frontArmFrameset, m_identity.personality.armIdle); + image = strf("{}:{}{}", m_frontArmFrameset, m_identity.personality.armIdle, prefix); position = m_identity.personality.armOffset / TilePixels; } else - image = strf("{}:{}.{}", m_frontArmFrameset, frameBase(m_state), armStateSeq); + image = strf("{}:{}.{}{}", m_frontArmFrameset, frameBase(m_state), armStateSeq, prefix); auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, position); - drawable.imagePart().addDirectives(getBodyDirectives(), true); + drawable.imagePart().addDirectives(bodyDirectives, true); if (dance.isValid()) drawable.rotate(danceStep->frontArmRotation); addDrawable(drawable, m_bodyFullbright); @@ -773,14 +784,15 @@ List Humanoid::render(bool withItems, bool withRotationAndScale) { if (!m_frontSleeveFrameset.empty()) { String image; Vec2F position; + auto prefix = m_chestArmorDirectives.prefix(); if (dance.isValid() && danceStep->frontArmFrame) { - image = strf("{}:{}", m_frontSleeveFrameset, *danceStep->frontArmFrame); + image = strf("{}:{}{}", m_frontSleeveFrameset, *danceStep->frontArmFrame, prefix); position = danceStep->frontArmOffset / TilePixels; } else if (m_state == Idle) { - image = strf("{}:{}", m_frontSleeveFrameset, m_identity.personality.armIdle); + image = strf("{}:{}{}", m_frontSleeveFrameset, m_identity.personality.armIdle, prefix); position = m_identity.personality.armOffset / TilePixels; } else - image = strf("{}:{}.{}", m_frontSleeveFrameset, frameBase(m_state), armStateSeq); + image = strf("{}:{}.{}{}", m_frontSleeveFrameset, frameBase(m_state), armStateSeq, prefix); auto drawable = Drawable::makeImage(image, 1.0f / TilePixels, true, position); drawable.imagePart().addDirectives(getChestDirectives(), true); if (dance.isValid()) From 01770c78db1bcc0dd94daea832611e6cd60e0287 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 5 Nov 2024 10:40:05 +1100 Subject: [PATCH 058/181] Disable stack capture on common Json patching exceptions Speeds up asset loading --- source/core/StarJsonPatch.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source/core/StarJsonPatch.cpp b/source/core/StarJsonPatch.cpp index 14505e5..88f9377 100644 --- a/source/core/StarJsonPatch.cpp +++ b/source/core/StarJsonPatch.cpp @@ -12,7 +12,7 @@ Json jsonPatch(Json const& base, JsonArray const& patch) { } return res; } catch (JsonException const& e) { - throw JsonPatchException(strf("Could not apply patch to base. {}", e.what())); + throw JsonPatchException(strf("Could not apply patch to base. {}", e.what()), false); } } @@ -26,7 +26,7 @@ size_t findJsonMatch(Json const& searchable, Json const& value, JsonPath::Pointe return i + 1; } } else { - throw JsonPatchException(strf("Search operation failure, value at '{}' is not an array.", pointer.path())); + throw JsonPatchException(strf("Search operation failure, value at '{}' is not an array.", pointer.path()), false); } return 0; } @@ -49,9 +49,9 @@ namespace JsonPatching { auto operation = op.getString("op"); return JsonPatching::functionMap.get(operation)(base, op); } catch (JsonException const& e) { - throw JsonPatchException(strf("Could not apply operation to base. {}", e.what())); + throw JsonPatchException(strf("Could not apply operation to base. {}", e.what()), false); } catch (MapException const&) { - throw JsonPatchException(strf("Invalid operation: {}", op.getString("op"))); + throw JsonPatchException(strf("Invalid operation: {}", op.getString("op")), false); } } @@ -66,28 +66,28 @@ namespace JsonPatching { auto searchValue = op.get("search"); bool found = findJsonMatch(searchable, searchValue, pointer); if (found && inverseTest) - throw JsonPatchTestFail(strf("Test operation failure, expected {} to be missing.", searchValue)); + throw JsonPatchTestFail(strf("Test operation failure, expected {} to be missing.", searchValue), false); else if (!found && !inverseTest) - throw JsonPatchTestFail(strf("Test operation failure, could not find {}.", searchValue)); + throw JsonPatchTestFail(strf("Test operation failure, could not find {}.", searchValue), false); return base; } else { auto value = op.opt("value"); auto testValue = pointer.get(base); if (!value) { if (inverseTest) - throw JsonPatchTestFail(strf("Test operation failure, expected {} to be missing.", path)); + throw JsonPatchTestFail(strf("Test operation failure, expected {} to be missing.", path), false); return base; } if ((value && (testValue == *value)) ^ inverseTest) return base; else - throw JsonPatchTestFail(strf("Test operation failure, expected {} found {}.", value, testValue)); + throw JsonPatchTestFail(strf("Test operation failure, expected {} found {}.", value, testValue), false); } } catch (JsonPath::TraversalException& e) { if (inverseTest) return base; - throw JsonPatchTestFail(strf("Test operation failure: {}", e.what())); + throw JsonPatchTestFail(strf("Test operation failure: {}", e.what()), false); } } From 49cadf79023016ce534c0137c53d342c0f23e875 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 5 Nov 2024 10:40:32 +1100 Subject: [PATCH 059/181] Fix crash when a quest adds a new quest in its update() call --- source/game/StarQuestManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/game/StarQuestManager.cpp b/source/game/StarQuestManager.cpp index df8a19a..8b85355 100644 --- a/source/game/StarQuestManager.cpp +++ b/source/game/StarQuestManager.cpp @@ -408,9 +408,9 @@ void QuestManager::update(float dt) { } } - for (auto& q : m_quests) { - if (questValidOnServer(q.second)) - q.second->update(dt); + for (auto& q : m_quests.values()) { + if (questValidOnServer(q)) + q->update(dt); } } From 662a3769262df8e8e2c0e5b4e9fc9544fe140b7b Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 5 Nov 2024 10:52:52 +1100 Subject: [PATCH 060/181] Update StarDirectives.cpp --- source/core/StarDirectives.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/core/StarDirectives.cpp b/source/core/StarDirectives.cpp index b72e8ee..ea9d565 100644 --- a/source/core/StarDirectives.cpp +++ b/source/core/StarDirectives.cpp @@ -161,8 +161,10 @@ StringView Directives::prefix() const { return ""; else if (m_shared->empty()) return m_shared->string; + else if (m_shared->string.utf8().at(0) == '?') + return ""; else - return StringView(m_shared->string).substr(0, m_shared->entries.begin()->begin); + return m_shared->entries.front().string(*m_shared); } String Directives::string() const { From 4b0b0474487861211585da47aca51ff462104848 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 5 Nov 2024 10:56:20 +1100 Subject: [PATCH 061/181] Update StarQuestManager.cpp --- source/game/StarQuestManager.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/source/game/StarQuestManager.cpp b/source/game/StarQuestManager.cpp index 8b85355..4e88500 100644 --- a/source/game/StarQuestManager.cpp +++ b/source/game/StarQuestManager.cpp @@ -73,10 +73,10 @@ void QuestManager::setUniverseClient(UniverseClient* client) { void QuestManager::init(World* world) { m_world = world; - for (auto& quest : m_quests) { - if (!questValidOnServer(quest.second)) + for (auto& quest : m_quests.values()) { + if (!questValidOnServer(quest)) continue; - quest.second->init(m_player, world, m_client); + quest->init(m_player, world, m_client); } m_trackOnWorldQuests = true; @@ -398,19 +398,21 @@ void QuestManager::update(float dt) { } } - for (auto& entry : m_quests) { + StringMap allQuests = quests(); + for (auto& entry : allQuests) { auto quest = entry.second; QuestState state = quest->state(); bool finished = state == QuestState::Complete || state == QuestState::Failed; if (state == QuestState::New || (finished && quest->ephemeral() && !quest->showDialog())) { quest->uninit(); + allQuests.remove(entry.first); m_quests.remove(entry.first); } } - for (auto& q : m_quests.values()) { - if (questValidOnServer(q)) - q->update(dt); + for (auto& q : allQuests) { + if (questValidOnServer(q.second)) + q.second->update(dt); } } From c2ec41c391ced5fb7c3b17002967869bbe614b6a Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 5 Nov 2024 12:07:54 +1100 Subject: [PATCH 062/181] Update StarHumanoid.cpp --- source/game/StarHumanoid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/game/StarHumanoid.cpp b/source/game/StarHumanoid.cpp index 6dfe8e3..14af148 100644 --- a/source/game/StarHumanoid.cpp +++ b/source/game/StarHumanoid.cpp @@ -730,7 +730,7 @@ List Humanoid::render(bool withItems, bool withRotationAndScale) { } if (!m_headArmorFrameset.empty()) { - String image = strf("{}:normal", m_headArmorFrameset); + String image = strf("{}:normal{}", m_headArmorFrameset, m_headArmorDirectives.prefix()); auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, headPosition); drawable.imagePart().addDirectives(getHeadDirectives(), true); addDrawable(std::move(drawable)); From 7151c0cd9ebfc5180bfc663ddfbe5a670b42f195 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 5 Nov 2024 15:42:21 +1100 Subject: [PATCH 063/181] fix /startquest parsing the argument in an annoying way --- source/frontend/StarClientCommandProcessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/frontend/StarClientCommandProcessor.cpp b/source/frontend/StarClientCommandProcessor.cpp index ac87397..e0fe827 100644 --- a/source/frontend/StarClientCommandProcessor.cpp +++ b/source/frontend/StarClientCommandProcessor.cpp @@ -245,7 +245,7 @@ String ClientCommandProcessor::startQuest(String const& argumentsString) { if (!adminCommandAllowed()) return "You must be an admin to use this command."; - auto questArc = QuestArcDescriptor::fromJson(Json::parse(arguments.at(0))); + auto questArc = QuestArcDescriptor::fromJson(Json::parseSequence(arguments.at(0)).get(0)); m_universeClient->questManager()->offer(make_shared(questArc, 0, m_universeClient->mainPlayer().get())); return "Quest started"; } From 9502b05ea4587f2c060608718486d5c8d5bc3ac5 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 5 Nov 2024 15:42:32 +1100 Subject: [PATCH 064/181] Update StarQuestManager.cpp --- source/game/StarQuestManager.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/source/game/StarQuestManager.cpp b/source/game/StarQuestManager.cpp index 4e88500..4dbc652 100644 --- a/source/game/StarQuestManager.cpp +++ b/source/game/StarQuestManager.cpp @@ -398,19 +398,21 @@ void QuestManager::update(float dt) { } } - StringMap allQuests = quests(); - for (auto& entry : allQuests) { + List expiredQuests; + for (auto& entry : m_quests) { auto quest = entry.second; QuestState state = quest->state(); bool finished = state == QuestState::Complete || state == QuestState::Failed; if (state == QuestState::New || (finished && quest->ephemeral() && !quest->showDialog())) { quest->uninit(); - allQuests.remove(entry.first); - m_quests.remove(entry.first); + expiredQuests.append(entry.first); } } - for (auto& q : allQuests) { + for (auto& questId : expiredQuests) + m_quests.remove(questId); + + for (auto& q : m_quests) { if (questValidOnServer(q.second)) q.second->update(dt); } From 3b40e89b3297a97a833711dbb77734b0412ac1d9 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 7 Nov 2024 18:26:31 +1100 Subject: [PATCH 065/181] Add camera bindings override missing, but it's a start --- source/client/StarClientApplication.cpp | 2 ++ source/game/CMakeLists.txt | 4 +++ .../{rendering => game}/StarWorldCamera.cpp | 2 +- .../{rendering => game}/StarWorldCamera.hpp | 10 +++--- .../game/scripting/StarCameraLuaBindings.cpp | 31 +++++++++++++++++++ .../game/scripting/StarCameraLuaBindings.hpp | 12 +++++++ source/rendering/CMakeLists.txt | 2 -- 7 files changed, 55 insertions(+), 8 deletions(-) rename source/{rendering => game}/StarWorldCamera.cpp (95%) rename source/{rendering => game}/StarWorldCamera.hpp (92%) create mode 100644 source/game/scripting/StarCameraLuaBindings.cpp create mode 100644 source/game/scripting/StarCameraLuaBindings.hpp diff --git a/source/client/StarClientApplication.cpp b/source/client/StarClientApplication.cpp index 5f0c22e..250445c 100644 --- a/source/client/StarClientApplication.cpp +++ b/source/client/StarClientApplication.cpp @@ -22,6 +22,7 @@ #include "StarInterfaceLuaBindings.hpp" #include "StarInputLuaBindings.hpp" #include "StarVoiceLuaBindings.hpp" +#include "StarCameraLuaBindings.hpp" #include "StarClipboardLuaBindings.hpp" #if defined STAR_SYSTEM_WINDOWS @@ -541,6 +542,7 @@ void ClientApplication::changeState(MainAppState newState) { m_universeClient->setLuaCallbacks("input", LuaBindings::makeInputCallbacks()); m_universeClient->setLuaCallbacks("voice", LuaBindings::makeVoiceCallbacks()); + m_universeClient->setLuaCallbacks("camera", LuaBindings::makeCameraCallbacks(&m_worldPainter->camera())); if (!m_root->configuration()->get("safeScripts").toBool()) m_universeClient->setLuaCallbacks("clipboard", LuaBindings::makeClipboardCallbacks(appController())); diff --git a/source/game/CMakeLists.txt b/source/game/CMakeLists.txt index 3b85e2a..affe2b3 100644 --- a/source/game/CMakeLists.txt +++ b/source/game/CMakeLists.txt @@ -162,6 +162,7 @@ SET (star_game_HEADERS StarWeatherTypes.hpp StarWireProcessor.hpp StarWiring.hpp + StarWorldCamera.hpp StarWorldClient.hpp StarWorldClientState.hpp StarWorldGeneration.hpp @@ -231,6 +232,7 @@ SET (star_game_HEADERS objects/StarPhysicsObject.hpp objects/StarTeleporterObject.hpp + scripting/StarCameraLuaBindings.hpp scripting/StarCelestialLuaBindings.hpp scripting/StarBehaviorLuaBindings.hpp scripting/StarConfigLuaBindings.hpp @@ -421,6 +423,7 @@ SET (star_game_SOURCES StarWeatherTypes.cpp StarWireProcessor.cpp StarWiring.cpp + StarWorldCamera.cpp StarWorldClient.cpp StarWorldClientState.cpp StarWorldGeneration.cpp @@ -470,6 +473,7 @@ SET (star_game_SOURCES objects/StarPhysicsObject.cpp objects/StarTeleporterObject.cpp + scripting/StarCameraLuaBindings.cpp scripting/StarCelestialLuaBindings.cpp scripting/StarBehaviorLuaBindings.cpp scripting/StarConfigLuaBindings.cpp diff --git a/source/rendering/StarWorldCamera.cpp b/source/game/StarWorldCamera.cpp similarity index 95% rename from source/rendering/StarWorldCamera.cpp rename to source/game/StarWorldCamera.cpp index de23f3e..a27f84a 100644 --- a/source/rendering/StarWorldCamera.cpp +++ b/source/game/StarWorldCamera.cpp @@ -2,7 +2,7 @@ namespace Star { -void WorldCamera::setCenterWorldPosition(Vec2F const& position, bool force) { +void WorldCamera::setCenterWorldPosition(Vec2F position, bool force) { m_rawWorldCenter = position; // Only actually move the world center if a half pixel distance has been // moved in any direction. This is sort of arbitrary, but helps prevent diff --git a/source/rendering/StarWorldCamera.hpp b/source/game/StarWorldCamera.hpp similarity index 92% rename from source/rendering/StarWorldCamera.hpp rename to source/game/StarWorldCamera.hpp index aa0713b..abc018a 100644 --- a/source/rendering/StarWorldCamera.hpp +++ b/source/game/StarWorldCamera.hpp @@ -20,7 +20,7 @@ public: // Set the camera center position (in world space) to as close to the given // location as possible while keeping the screen within world bounds. - void setCenterWorldPosition(Vec2F const& position, bool force = false); + void setCenterWorldPosition(Vec2F position, bool force = false); // Returns the actual camera position. Vec2F centerWorldPosition() const; @@ -28,10 +28,10 @@ public: // the world is non-euclidean, one world coordinate can transform to // potentially an infinite number of screen coordinates. This will retrun // the closest to the center of the screen. - Vec2F worldToScreen(Vec2F const& worldCoord) const; + Vec2F worldToScreen(Vec2F worldCoord) const; // Assumes top left corner of screen is (0, 0) in screen coordinates. - Vec2F screenToWorld(Vec2F const& screen) const; + Vec2F screenToWorld(Vec2F screen) const; // Returns screen dimensions in world space. RectF worldScreenRect() const; @@ -86,7 +86,7 @@ inline Vec2F WorldCamera::centerWorldPosition() const { return Vec2F(m_worldCenter); } -inline Vec2F WorldCamera::worldToScreen(Vec2F const& worldCoord) const { +inline Vec2F WorldCamera::worldToScreen(Vec2F worldCoord) const { Vec2F wrappedCoord = m_worldGeometry.nearestTo(Vec2F(m_worldCenter), worldCoord); return Vec2F( (wrappedCoord[0] - m_worldCenter[0]) * (TilePixels * m_pixelRatio) + (float)m_screenSize[0] / 2.0, @@ -94,7 +94,7 @@ inline Vec2F WorldCamera::worldToScreen(Vec2F const& worldCoord) const { ); } -inline Vec2F WorldCamera::screenToWorld(Vec2F const& screen) const { +inline Vec2F WorldCamera::screenToWorld(Vec2F screen) const { return Vec2F( (screen[0] - (float)m_screenSize[0] / 2.0) / (TilePixels * m_pixelRatio) + m_worldCenter[0], (screen[1] - (float)m_screenSize[1] / 2.0) / (TilePixels * m_pixelRatio) + m_worldCenter[1] diff --git a/source/game/scripting/StarCameraLuaBindings.cpp b/source/game/scripting/StarCameraLuaBindings.cpp new file mode 100644 index 0000000..b7128ea --- /dev/null +++ b/source/game/scripting/StarCameraLuaBindings.cpp @@ -0,0 +1,31 @@ +#include "StarCameraLuaBindings.hpp" +#include "StarLuaConverters.hpp" +#include "StarWorldCamera.hpp" +#include "StarRoot.hpp" + +namespace Star { + +LuaCallbacks LuaBindings::makeCameraCallbacks(WorldCamera* camera) { + LuaCallbacks callbacks; + + callbacks.registerCallbackWithSignature("position", bind(&WorldCamera::centerWorldPosition, camera)); + callbacks.registerCallbackWithSignature("pixelRatio", bind(&WorldCamera::pixelRatio, camera)); + callbacks.registerCallback("setPixelRatio", [camera](float pixelRatio, Maybe smooth) { + if (smooth.value()) + camera->setTargetPixelRatio(pixelRatio); + else + camera->setPixelRatio(pixelRatio); + Root::singleton().configuration()->set("zoomLevel", pixelRatio); + }); + + callbacks.registerCallbackWithSignature("screenSize", bind(&WorldCamera::screenSize, camera)); + callbacks.registerCallbackWithSignature("worldScreenRect", bind(&WorldCamera::worldScreenRect, camera)); + callbacks.registerCallbackWithSignature("worldTileRect", bind(&WorldCamera::worldTileRect, camera)); + callbacks.registerCallbackWithSignature("tileMinScreen", bind(&WorldCamera::tileMinScreen, camera)); + callbacks.registerCallbackWithSignature("screenToWorld", bind(&WorldCamera::screenToWorld, camera, _1)); + callbacks.registerCallbackWithSignature("worldToScreen", bind(&WorldCamera::worldToScreen, camera, _1)); + + return callbacks; +} + +} diff --git a/source/game/scripting/StarCameraLuaBindings.hpp b/source/game/scripting/StarCameraLuaBindings.hpp new file mode 100644 index 0000000..b944b3d --- /dev/null +++ b/source/game/scripting/StarCameraLuaBindings.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "StarLua.hpp" + +namespace Star { + +STAR_CLASS(WorldCamera); + +namespace LuaBindings { + LuaCallbacks makeCameraCallbacks(WorldCamera* camera); +} +} diff --git a/source/rendering/CMakeLists.txt b/source/rendering/CMakeLists.txt index 401f16e..f44f109 100644 --- a/source/rendering/CMakeLists.txt +++ b/source/rendering/CMakeLists.txt @@ -16,7 +16,6 @@ SET (star_rendering_HEADERS StarFontTextureGroup.hpp StarTextPainter.hpp StarTilePainter.hpp - StarWorldCamera.hpp StarWorldPainter.hpp ) @@ -28,7 +27,6 @@ SET (star_rendering_SOURCES StarFontTextureGroup.cpp StarTextPainter.cpp StarTilePainter.cpp - StarWorldCamera.cpp StarWorldPainter.cpp ) From 46f4b5b07e762bff563ec20d2a1c7ac6e2699b84 Mon Sep 17 00:00:00 2001 From: WasabiRaptor Date: Wed, 13 Nov 2024 17:16:19 -0500 Subject: [PATCH 066/181] add dedicated create character button to the CharSelectionPane so people don't have to scroll to the bottom of their character list to create new characters --- .../interface/windowconfig/charselection.config.patch | 9 +++++++++ source/frontend/StarCharSelection.cpp | 1 + 2 files changed, 10 insertions(+) create mode 100644 assets/opensb/interface/windowconfig/charselection.config.patch diff --git a/assets/opensb/interface/windowconfig/charselection.config.patch b/assets/opensb/interface/windowconfig/charselection.config.patch new file mode 100644 index 0000000..731a075 --- /dev/null +++ b/assets/opensb/interface/windowconfig/charselection.config.patch @@ -0,0 +1,9 @@ +[{"op":"merge", "path":"", "value": { + "createCharButton" : { + "type" : "button", + "base" : "/interface/title/createcharacter.png", + "hover" : "/interface/title/createcharacterover.png", + "position" : [23, 241], + "pressedOffset" : [0, 0] + } +}}] diff --git a/source/frontend/StarCharSelection.cpp b/source/frontend/StarCharSelection.cpp index 50b527d..4c56d59 100644 --- a/source/frontend/StarCharSelection.cpp +++ b/source/frontend/StarCharSelection.cpp @@ -27,6 +27,7 @@ CharSelectionPane::CharSelectionPane(PlayerStoragePtr playerStorage, guiReader.registerCallback("charSelector2", [=](Widget*) { selectCharacter(1); }); guiReader.registerCallback("charSelector3", [=](Widget*) { selectCharacter(2); }); guiReader.registerCallback("charSelector4", [=](Widget*) { selectCharacter(3); }); + guiReader.registerCallback("createCharButton", [=](Widget*) { m_createCallback(); }); guiReader.construct(root.assets()->json("/interface/windowconfig/charselection.config"), this); } From a59ff847bcc064aa78318d5c7161420595abe159 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 21 Nov 2024 15:31:28 +1100 Subject: [PATCH 067/181] Fix UB when a unique effect script adds another unique effect during initialization --- .../interface/windowconfig/charselection.config.patch | 4 ++-- source/game/StarStatusController.cpp | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/assets/opensb/interface/windowconfig/charselection.config.patch b/assets/opensb/interface/windowconfig/charselection.config.patch index 731a075..c904b44 100644 --- a/assets/opensb/interface/windowconfig/charselection.config.patch +++ b/assets/opensb/interface/windowconfig/charselection.config.patch @@ -1,4 +1,4 @@ -[{"op":"merge", "path":"", "value": { +{ "createCharButton" : { "type" : "button", "base" : "/interface/title/createcharacter.png", @@ -6,4 +6,4 @@ "position" : [23, 241], "pressedOffset" : [0, 0] } -}}] +} diff --git a/source/game/StarStatusController.cpp b/source/game/StarStatusController.cpp index 325fc17..26c83d0 100644 --- a/source/game/StarStatusController.cpp +++ b/source/game/StarStatusController.cpp @@ -410,8 +410,9 @@ void StatusController::init(Entity* parentEntity, ActorMovementController* movem if (m_parentEntity->isMaster()) { initPrimaryScript(); - for (auto& p : m_uniqueEffects) - initUniqueEffectScript(p.second); + for (auto& p : m_uniqueEffects.keys()) + if (auto effect = m_uniqueEffects.ptr(p)) + initUniqueEffectScript(*effect); } m_environmentStatusEffectUpdateTimer.reset(); @@ -421,8 +422,9 @@ void StatusController::uninit() { m_parentEntity = nullptr; m_movementController = nullptr; - for (auto& p : m_uniqueEffects) - uninitUniqueEffectScript(p.second); + for (auto& p : m_uniqueEffects.keys()) + if (auto effect = m_uniqueEffects.ptr(p)) + uninitUniqueEffectScript(*effect); uninitPrimaryScript(); m_recentHitsGiven.reset(); From d4c976bcb3ec75c94298c6b8776487809367498b Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 21 Nov 2024 15:58:53 +1100 Subject: [PATCH 068/181] Add prefix Humanoid fix to portraits --- source/game/StarHumanoid.cpp | 70 +++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/source/game/StarHumanoid.cpp b/source/game/StarHumanoid.cpp index 14af148..c71e161 100644 --- a/source/game/StarHumanoid.cpp +++ b/source/game/StarHumanoid.cpp @@ -852,104 +852,118 @@ List Humanoid::renderPortrait(PortraitMode mode) const { if (mode != PortraitMode::Head) { if (!m_backArmFrameset.empty()) { - String image = strf("{}:{}", m_backArmFrameset, personality.armIdle); + auto bodyDirectives = getBodyDirectives(); + String image = strf("{}:{}{}", m_backArmFrameset, personality.armIdle, bodyDirectives.prefix()); Drawable drawable = Drawable::makeImage(std::move(image), 1.0f, true, personality.armOffset); - drawable.imagePart().addDirectives(getBodyDirectives(), true); + drawable.imagePart().addDirectives(bodyDirectives, true); addDrawable(std::move(drawable)); } if (dressed && !m_backSleeveFrameset.empty()) { - String image = strf("{}:{}", m_backSleeveFrameset, personality.armIdle); + auto chestDirectives = getChestDirectives(); + String image = strf("{}:{}{}", m_backSleeveFrameset, personality.armIdle, chestDirectives.prefix()); Drawable drawable = Drawable::makeImage(std::move(image), 1.0f, true, personality.armOffset); - drawable.imagePart().addDirectives(getChestDirectives(), true); + drawable.imagePart().addDirectives(chestDirectives, true); addDrawable(std::move(drawable)); } if (mode != PortraitMode::Bust) { if (dressed && !m_backArmorFrameset.empty()) { - String image = strf("{}:{}", m_backArmorFrameset, personality.idle); + auto backDirectives = getBackDirectives(); + String image = strf("{}:{}{}", m_backArmorFrameset, personality.idle, backDirectives.prefix()); Drawable drawable = Drawable::makeImage(std::move(image), 1.0f, true, {}); - drawable.imagePart().addDirectives(getBackDirectives(), true); + drawable.imagePart().addDirectives(backDirectives, true); addDrawable(std::move(drawable)); } } } if (!m_headFrameset.empty()) { - String image = strf("{}:normal", m_headFrameset); + auto bodyDirectives = getBodyDirectives(); + String image = strf("{}:normal{}", m_headFrameset, bodyDirectives.prefix()); Drawable drawable = Drawable::makeImage(std::move(image), 1.0f, true, personality.headOffset); - drawable.imagePart().addDirectives(getBodyDirectives(), true); + drawable.imagePart().addDirectives(bodyDirectives, true); addDrawable(std::move(drawable)); } if (!m_emoteFrameset.empty()) { - String image = strf("{}:{}.{}", m_emoteFrameset, emoteFrameBase(m_emoteState), emoteStateSeq); + auto emoteDirectives = getEmoteDirectives(); + String image = strf("{}:{}.{}{}", m_emoteFrameset, emoteFrameBase(m_emoteState), emoteStateSeq, emoteDirectives.prefix()); Drawable drawable = Drawable::makeImage(std::move(image), 1.0f, true, personality.headOffset); - drawable.imagePart().addDirectives(getEmoteDirectives(), true); + drawable.imagePart().addDirectives(emoteDirectives, true); addDrawable(std::move(drawable)); } if (!m_hairFrameset.empty()) { - String image = strf("{}:normal", m_hairFrameset); + auto hairDirectives = getHairDirectives(); + String image = strf("{}:normal{}", m_hairFrameset, hairDirectives.prefix()); Drawable drawable = Drawable::makeImage(std::move(image), 1.0f, true, personality.headOffset); - drawable.imagePart().addDirectives(getHairDirectives(), true).addDirectives(helmetMaskDirective, true); + drawable.imagePart().addDirectives(hairDirectives, true).addDirectives(helmetMaskDirective, true); addDrawable(std::move(drawable)); } if (!m_bodyFrameset.empty()) { - String image = strf("{}:{}", m_bodyFrameset, personality.idle); + auto bodyDirectives = getBodyDirectives(); + String image = strf("{}:{}{}", m_bodyFrameset, personality.idle, bodyDirectives.prefix()); Drawable drawable = Drawable::makeImage(std::move(image), 1.0f, true, {}); - drawable.imagePart().addDirectives(getBodyDirectives(), true); + drawable.imagePart().addDirectives(bodyDirectives, true); addDrawable(std::move(drawable)); } if (mode != PortraitMode::Head) { if (dressed && !m_legsArmorFrameset.empty()) { - String image = strf("{}:{}", m_legsArmorFrameset, personality.idle); + auto legsDirectives = getLegsDirectives(); + String image = strf("{}:{}{}", m_legsArmorFrameset, personality.idle, legsDirectives.prefix()); Drawable drawable = Drawable::makeImage(std::move(image), 1.0f, true, {}); - drawable.imagePart().addDirectives(getLegsDirectives(), true); + drawable.imagePart().addDirectives(legsDirectives, true); addDrawable(std::move(drawable)); } if (dressed && !m_chestArmorFrameset.empty()) { - String image = strf("{}:{}", m_chestArmorFrameset, personality.idle); + auto chestDirectives = getChestDirectives(); + String image = strf("{}:{}{}", m_chestArmorFrameset, personality.idle, chestDirectives.prefix()); Drawable drawable = Drawable::makeImage(std::move(image), 1.0f, true, {}); - drawable.imagePart().addDirectives(getChestDirectives(), true); + drawable.imagePart().addDirectives(chestDirectives, true); addDrawable(std::move(drawable)); } } if (!m_facialHairFrameset.empty()) { - String image = strf("{}:normal", m_facialHairFrameset); + auto facialHairDirectives = getFacialHairDirectives(); + String image = strf("{}:normal{}", m_facialHairFrameset, facialHairDirectives.prefix()); Drawable drawable = Drawable::makeImage(std::move(image), 1.0f, true, personality.headOffset); - drawable.imagePart().addDirectives(getFacialHairDirectives(), true).addDirectives(helmetMaskDirective, true); + drawable.imagePart().addDirectives(facialHairDirectives, true).addDirectives(helmetMaskDirective, true); addDrawable(std::move(drawable)); } if (!m_facialMaskFrameset.empty()) { - String image = strf("{}:normal", m_facialMaskFrameset); + auto facialMaskDirectives = getFacialMaskDirectives(); + String image = strf("{}:normal{}", m_facialMaskFrameset, facialMaskDirectives.prefix()); Drawable drawable = Drawable::makeImage(std::move(image), 1.0f, true, personality.headOffset); - drawable.imagePart().addDirectives(getFacialMaskDirectives(), true).addDirectives(helmetMaskDirective, true); + drawable.imagePart().addDirectives(facialMaskDirectives, true).addDirectives(helmetMaskDirective, true); addDrawable(std::move(drawable)); } if (dressed && !m_headArmorFrameset.empty()) { - String image = strf("{}:normal", m_headArmorFrameset); + auto headDirectives = getHeadDirectives(); + String image = strf("{}:normal{}", m_headArmorFrameset, headDirectives.prefix()); Drawable drawable = Drawable::makeImage(std::move(image), 1.0f, true, personality.headOffset); - drawable.imagePart().addDirectives(getHeadDirectives(), true); + drawable.imagePart().addDirectives(headDirectives, true); addDrawable(std::move(drawable)); } if (mode != PortraitMode::Head) { if (!m_frontArmFrameset.empty()) { - String image = strf("{}:{}", m_frontArmFrameset, personality.armIdle); + auto bodyDirectives = getBodyDirectives(); + String image = strf("{}:{}{}", m_frontArmFrameset, personality.armIdle, bodyDirectives.prefix()); Drawable drawable = Drawable::makeImage(std::move(image), 1.0f, true, personality.armOffset); - drawable.imagePart().addDirectives(getBodyDirectives(), true); + drawable.imagePart().addDirectives(bodyDirectives, true); addDrawable(std::move(drawable)); } if (dressed && !m_frontSleeveFrameset.empty()) { - String image = strf("{}:{}", m_frontSleeveFrameset, personality.armIdle); + auto chestDirectives = getChestDirectives(); + String image = strf("{}:{}{}", m_frontSleeveFrameset, personality.armIdle, chestDirectives.prefix()); Drawable drawable = Drawable::makeImage(std::move(image), 1.0f, true, personality.armOffset); - drawable.imagePart().addDirectives(getChestDirectives(), true); + drawable.imagePart().addDirectives(chestDirectives, true); addDrawable(std::move(drawable)); } } From 56c99c086fd14ee1b1131cb7df18c1b55ede5519 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sun, 24 Nov 2024 12:51:55 +1100 Subject: [PATCH 069/181] scriptable chat --- source/client/StarClientApplication.cpp | 3 +- source/frontend/StarBaseScriptPane.cpp | 25 ++-- source/frontend/StarBaseScriptPane.hpp | 6 +- source/frontend/StarChat.cpp | 156 ++++++++++++++++-------- source/frontend/StarChat.hpp | 7 +- source/frontend/StarMainInterface.cpp | 14 ++- source/frontend/StarMainInterface.hpp | 1 + source/game/StarUniverseClient.cpp | 4 + source/game/StarUniverseClient.hpp | 1 + source/windowing/StarPane.cpp | 12 ++ 10 files changed, 158 insertions(+), 71 deletions(-) diff --git a/source/client/StarClientApplication.cpp b/source/client/StarClientApplication.cpp index 250445c..b4e0955 100644 --- a/source/client/StarClientApplication.cpp +++ b/source/client/StarClientApplication.cpp @@ -684,8 +684,9 @@ void ClientApplication::changeState(MainAppState newState) { m_mainInterface = make_shared(m_universeClient, m_worldPainter, m_cinematicOverlay); m_universeClient->setLuaCallbacks("interface", LuaBindings::makeInterfaceCallbacks(m_mainInterface.get())); m_universeClient->setLuaCallbacks("chat", LuaBindings::makeChatCallbacks(m_mainInterface.get(), m_universeClient.get())); - m_universeClient->startLua(); + m_mainInterface->displayDefaultPanes(); + m_universeClient->startLua(); m_mainMixer->setWorldPainter(m_worldPainter); if (auto renderer = Application::renderer()) { diff --git a/source/frontend/StarBaseScriptPane.cpp b/source/frontend/StarBaseScriptPane.cpp index bfeebb7..63dbd08 100644 --- a/source/frontend/StarBaseScriptPane.cpp +++ b/source/frontend/StarBaseScriptPane.cpp @@ -14,7 +14,7 @@ namespace Star { -BaseScriptPane::BaseScriptPane(Json config) : Pane(), m_rawConfig(config) { +BaseScriptPane::BaseScriptPane(Json config, bool construct) : Pane(), m_rawConfig(config) { auto& root = Root::singleton(); auto assets = root.assets(); @@ -35,15 +35,8 @@ BaseScriptPane::BaseScriptPane(Json config) : Pane(), m_rawConfig(config) { }); } - m_reader->construct(assets->fetchJson(m_config.get("gui")), this); - - for (auto pair : m_config.getObject("canvasClickCallbacks", {})) - m_canvasClickCallbacks.set(findChild(pair.first), pair.second.toString()); - for (auto pair : m_config.getObject("canvasKeyCallbacks", {})) - m_canvasKeyCallbacks.set(findChild(pair.first), pair.second.toString()); - - m_script.setScripts(jsonToStringList(m_config.get("scripts", JsonArray()))); - m_script.setUpdateDelta(m_config.getUInt("scriptDelta", 1)); + if (construct) + this->construct(assets->fetchJson(m_config.get("gui"))); m_callbacksAdded = false; } @@ -140,4 +133,16 @@ GuiReaderPtr BaseScriptPane::reader() { return m_reader; } +void BaseScriptPane::construct(Json config) { + m_reader->construct(config, this); + + for (auto pair : m_config.getObject("canvasClickCallbacks", {})) + m_canvasClickCallbacks.set(findChild(pair.first), pair.second.toString()); + for (auto pair : m_config.getObject("canvasKeyCallbacks", {})) + m_canvasKeyCallbacks.set(findChild(pair.first), pair.second.toString()); + + m_script.setScripts(jsonToStringList(m_config.get("scripts", JsonArray()))); + m_script.setUpdateDelta(m_config.getUInt("scriptDelta", 1)); +} + } diff --git a/source/frontend/StarBaseScriptPane.hpp b/source/frontend/StarBaseScriptPane.hpp index 0c00547..08a4d69 100644 --- a/source/frontend/StarBaseScriptPane.hpp +++ b/source/frontend/StarBaseScriptPane.hpp @@ -15,7 +15,7 @@ STAR_CLASS(BaseScriptPane); class BaseScriptPane : public Pane { public: - BaseScriptPane(Json config); + BaseScriptPane(Json config, bool construct = true); virtual void show() override; void displayed() override; @@ -34,6 +34,8 @@ public: Maybe cursorOverride(Vec2I const& screenPosition) override; protected: virtual GuiReaderPtr reader() override; + void construct(Json config); + Json m_config; Json m_rawConfig; @@ -45,7 +47,7 @@ protected: bool m_interactive; bool m_callbacksAdded; - LuaUpdatableComponent m_script; + mutable LuaUpdatableComponent m_script; }; } diff --git a/source/frontend/StarChat.cpp b/source/frontend/StarChat.cpp index bbb28c1..da6c421 100644 --- a/source/frontend/StarChat.cpp +++ b/source/frontend/StarChat.cpp @@ -13,14 +13,25 @@ #include "StarPlayerStorage.hpp" #include "StarTeamClient.hpp" +#include "StarPlayer.hpp" +#include "StarConfigLuaBindings.hpp" +#include "StarPlayerLuaBindings.hpp" +#include "StarStatusControllerLuaBindings.hpp" +#include "StarCelestialLuaBindings.hpp" +#include "StarLuaGameConverters.hpp" + namespace Star { -Chat::Chat(UniverseClientPtr client) : m_client(client) { +Chat::Chat(UniverseClientPtr client, Json const& baseConfig) : BaseScriptPane(baseConfig, false) { + m_client = client; + m_scripted = baseConfig.get("scripts", Json()).isType(Json::Type::Array); + m_script.setLuaRoot(m_client->luaRoot()); + m_script.addCallbacks("world", LuaBindings::makeWorldCallbacks((World*)m_client->worldClient().get())); m_chatPrevIndex = 0; m_historyOffset = 0; - + auto assets = Root::singleton().assets(); - auto config = assets->json("/interface/chat/chat.config:config"); + auto config = baseConfig.get("config"); m_timeChatLastActive = Time::monotonicMilliseconds(); m_chatTextStyle = config.get("textStyle"); m_chatTextStyle.lineSpacing = config.get("lineHeight").toFloat(); @@ -45,15 +56,13 @@ Chat::Chat(UniverseClientPtr client) : m_client(client) { m_colorCodes[MessageContext::CommandResult] = config.query("colors.commandResult").toString(); m_colorCodes[MessageContext::RadioMessage] = config.query("colors.radioMessage").toString(); m_colorCodes[MessageContext::World] = config.query("colors.world").toString(); + if (!m_scripted) { + m_reader->registerCallback("textBox", [=](Widget*) { startChat(); }); + m_reader->registerCallback("upButton", [=](Widget*) { scrollUp(); }); + m_reader->registerCallback("downButton", [=](Widget*) { scrollDown(); }); + m_reader->registerCallback("bottomButton", [=](Widget*) { scrollBottom(); }); - GuiReader reader; - - reader.registerCallback("textBox", [=](Widget*) { startChat(); }); - reader.registerCallback("upButton", [=](Widget*) { scrollUp(); }); - reader.registerCallback("downButton", [=](Widget*) { scrollDown(); }); - reader.registerCallback("bottomButton", [=](Widget*) { scrollBottom(); }); - - reader.registerCallback("filterGroup", [=](Widget* widget) { + m_reader->registerCallback("filterGroup", [=](Widget* widget) { Json data = as(widget)->data(); auto filter = data.getArray("filter", {}); m_modeFilter.clear(); @@ -62,41 +71,49 @@ Chat::Chat(UniverseClientPtr client) : m_client(client) { m_sendMode = ChatSendModeNames.getLeft(data.getString("sendMode", "Broadcast")); m_historyOffset = 0; }); + } + + construct(baseConfig.get("gui")); m_sendMode = ChatSendMode::Broadcast; - - reader.construct(assets->json("/interface/chat/chat.config:gui"), this); - - m_textBox = fetchChild("textBox"); - m_say = fetchChild("say"); - m_chatLog = fetchChild("chatLog"); - if (auto logPadding = config.optQuery("padding")) { - m_chatLogPadding = jsonToVec2I(logPadding.get()); - m_chatLog->setSize(m_chatLog->size() + m_chatLogPadding * 2); - m_chatLog->setPosition(m_chatLog->position() - m_chatLogPadding); - } - else - m_chatLogPadding = Vec2I(); - m_bottomButton = fetchChild("bottomButton"); m_upButton = fetchChild("upButton"); + m_textBox = fetchChild("textBox"); + m_say = fetchChild("say"); + if (!m_scripted) { + if (auto logPadding = config.optQuery("padding")) { + m_chatLogPadding = jsonToVec2I(logPadding.get()); + m_chatLog->setSize(m_chatLog->size() + m_chatLogPadding * 2); + m_chatLog->setPosition(m_chatLog->position() - m_chatLogPadding); + } else + m_chatLogPadding = Vec2I(); - m_chatHistory.appendAll(m_client->playerStorage()->getMetadata("chatHistory").opt().apply(jsonToStringList).value()); + m_chatHistory.appendAll(m_client->playerStorage()->getMetadata("chatHistory").opt().apply(jsonToStringList).value()); + } else { + m_script.addCallbacks("player", LuaBindings::makePlayerCallbacks(m_client->mainPlayer().get())); + m_script.addCallbacks("status", LuaBindings::makeStatusControllerCallbacks(m_client->mainPlayer()->statusController())); + m_script.addCallbacks("celestial", LuaBindings::makeCelestialCallbacks(m_client.get())); + } show(); - updateBottomButton(); + //if (!m_scripted) { + //updateBottomButton(); - m_background = fetchChild("background"); - m_defaultHeight = m_background->size()[1]; - m_expanded = false; - updateSize(); + m_background = fetchChild("background"); + m_defaultHeight = m_background->size()[1]; + m_expanded = false; + updateSize(); + //} } void Chat::update(float dt) { Pane::update(dt); + if (m_scripted) + return; + auto team = m_client->teamClient()->currentTeam(); for (auto button : fetchChild("filterGroup")->buttons()) { auto mode = ChatSendModeNames.getLeft(button->data().getString("sendMode", "Broadcast")); @@ -108,40 +125,64 @@ void Chat::update(float dt) { } void Chat::startChat() { - show(); - m_textBox->focus(); + if (m_scripted) + m_script.invoke("startChat"); + else { + show(); + m_textBox->focus(); + } } void Chat::startCommand() { - show(); - m_textBox->setText("/"); - m_textBox->focus(); + if (m_scripted) + m_script.invoke("startCommand"); + else { + show(); + m_textBox->setText("/"); + m_textBox->focus(); + } } bool Chat::hasFocus() const { + if (m_scripted) + return m_script.invoke("hasFocus").value(); return m_textBox->hasFocus(); } void Chat::stopChat() { - m_textBox->setText(""); - m_textBox->blur(); - m_timeChatLastActive = Time::monotonicMilliseconds(); + if (m_scripted) + m_script.invoke("stopChat"); + else { + m_textBox->setText(""); + m_textBox->blur(); + m_timeChatLastActive = Time::monotonicMilliseconds(); + } } String Chat::currentChat() const { + if (m_scripted) + return m_script.invoke("currentChat").value(); return m_textBox->getText(); } bool Chat::setCurrentChat(String const& chat, bool moveCursor) { + if (m_scripted) + return m_script.invoke("setCurrentChat").value(); return m_textBox->setText(chat, true, moveCursor); } void Chat::clearCurrentChat() { - m_textBox->setText(""); - m_chatPrevIndex = 0; + if (m_scripted) + m_script.invoke("clearCurrentChat"); + else { + m_textBox->setText(""); + m_chatPrevIndex = 0; + } } ChatSendMode Chat::sendMode() const { + if (m_scripted) + return ChatSendModeNames.getLeft(m_script.invoke("sendMode").value()); return m_sendMode; } @@ -171,6 +212,13 @@ void Chat::addMessages(List const& messages, bool showPane) if (messages.empty()) return; + if (m_scripted) { + m_script.invoke("addMessages", messages.transformed([](ChatReceivedMessage const& message) { + return message.toJson(); + }), showPane); + return; + } + GuiContext& guiContext = GuiContext::singleton(); for (auto const& message : messages) { @@ -209,17 +257,22 @@ void Chat::addMessages(List const& messages, bool showPane) } void Chat::addHistory(String const& chat) { - if (m_chatHistory.size() > 0 && m_chatHistory.get(0).equals(chat)) + if (m_scripted) + m_script.invoke("addHistory", chat); + else if (m_chatHistory.size() > 0 && m_chatHistory.get(0).equals(chat)) return; - - m_chatHistory.prepend(chat); - m_chatHistory.resize(std::min((unsigned)m_chatHistory.size(), m_chatHistoryLimit)); - m_timeChatLastActive = Time::monotonicMilliseconds(); - m_client->playerStorage()->setMetadata("chatHistory", JsonArray::from(m_chatHistory)); + else { + m_chatHistory.prepend(chat); + m_chatHistory.resize(std::min((unsigned)m_chatHistory.size(), m_chatHistoryLimit)); + m_timeChatLastActive = Time::monotonicMilliseconds(); + m_client->playerStorage()->setMetadata("chatHistory", JsonArray::from(m_chatHistory)); + } } void Chat::clear(size_t count) { - if (count > m_receivedMessages.size()) + if (m_scripted) + m_script.invoke("clear", count); + else if (count > m_receivedMessages.size()) m_receivedMessages.clear(); else m_receivedMessages.erase(m_receivedMessages.begin(), m_receivedMessages.begin() + count); @@ -227,6 +280,8 @@ void Chat::clear(size_t count) { void Chat::renderImpl() { Pane::renderImpl(); + if (m_scripted) + return; if (m_textBox->hasFocus()) m_timeChatLastActive = Time::monotonicMilliseconds(); Vec4B fade = {255, 255, 255, 255}; @@ -303,6 +358,9 @@ void Chat::hide() { } float Chat::visible() const { + if (m_scripted) + return m_script.invoke("visible").value(1.0f); + double difference = (Time::monotonicMilliseconds() - m_timeChatLastActive) / 1000.0; if (difference < m_chatVisTime) return 1; @@ -310,7 +368,7 @@ float Chat::visible() const { } bool Chat::sendEvent(InputEvent const& event) { - if (active()) { + if (!m_scripted && active()) { if (hasFocus()) { if (event.is()) { auto actions = context()->actions(event); diff --git a/source/frontend/StarChat.hpp b/source/frontend/StarChat.hpp index df2d63c..53ed578 100644 --- a/source/frontend/StarChat.hpp +++ b/source/frontend/StarChat.hpp @@ -1,6 +1,6 @@ #pragma once -#include "StarPane.hpp" +#include "StarBaseScriptPane.hpp" #include "StarChatTypes.hpp" namespace Star { @@ -13,9 +13,9 @@ STAR_CLASS(ImageStretchWidget); STAR_CLASS(CanvasWidget); STAR_CLASS(Chat); -class Chat : public Pane { +class Chat : public BaseScriptPane { public: - Chat(UniverseClientPtr client); + Chat(UniverseClientPtr client, Json const&); void startChat(); void startCommand(); @@ -57,6 +57,7 @@ private: void updateBottomButton(); UniverseClientPtr m_client; + bool m_scripted; TextBoxWidgetPtr m_textBox; LabelWidgetPtr m_say; diff --git a/source/frontend/StarMainInterface.cpp b/source/frontend/StarMainInterface.cpp index 153ce07..41eceb7 100644 --- a/source/frontend/StarMainInterface.cpp +++ b/source/frontend/StarMainInterface.cpp @@ -141,7 +141,7 @@ MainInterface::MainInterface(UniverseClientPtr client, WorldPainterPtr painter, m_collections = make_shared(m_client, "/interface/scripted/collections/collectionsgui.config"); m_paneManager.registerPane(MainInterfacePanes::Collections, PaneLayer::Window, m_collections); - m_chat = make_shared(m_client); + m_chat = make_shared(m_client, Root::singleton().assets()->json("/interface/chat/chat.config")); m_paneManager.registerPane(MainInterfacePanes::Chat, PaneLayer::Hud, m_chat); m_clientCommandProcessor = make_shared(m_client, m_cinematicOverlay, &m_paneManager, m_config->macroCommands); @@ -171,11 +171,6 @@ MainInterface::MainInterface(UniverseClientPtr client, WorldPainterPtr painter, m_nameplatePainter = make_shared(); m_questIndicatorPainter = make_shared(m_client); m_chatBubbleManager = make_shared(); - - m_paneManager.displayRegisteredPane(MainInterfacePanes::ActionBar); - m_paneManager.displayRegisteredPane(MainInterfacePanes::Chat); - m_paneManager.displayRegisteredPane(MainInterfacePanes::TeamBar); - m_paneManager.displayRegisteredPane(MainInterfacePanes::StatusPane); } MainInterface::~MainInterface() { @@ -997,6 +992,13 @@ void MainInterface::reviveScriptPanes(List& panes) { } } +void MainInterface::displayDefaultPanes() { + m_paneManager.displayRegisteredPane(MainInterfacePanes::ActionBar); + m_paneManager.displayRegisteredPane(MainInterfacePanes::Chat); + m_paneManager.displayRegisteredPane(MainInterfacePanes::TeamBar); + m_paneManager.displayRegisteredPane(MainInterfacePanes::StatusPane); +} + PanePtr MainInterface::createEscapeDialog() { auto assets = Root::singleton().assets(); diff --git a/source/frontend/StarMainInterface.hpp b/source/frontend/StarMainInterface.hpp index 667a2fe..a4f617b 100644 --- a/source/frontend/StarMainInterface.hpp +++ b/source/frontend/StarMainInterface.hpp @@ -132,6 +132,7 @@ public: void takeScriptPanes(List& out); void reviveScriptPanes(List& panes); + void displayDefaultPanes(); private: PanePtr createEscapeDialog(); diff --git a/source/game/StarUniverseClient.cpp b/source/game/StarUniverseClient.cpp index d739f5a..427cecb 100644 --- a/source/game/StarUniverseClient.cpp +++ b/source/game/StarUniverseClient.cpp @@ -519,6 +519,10 @@ void UniverseClient::stopLua() { m_scriptContexts.clear(); } +LuaRootPtr UniverseClient::luaRoot() { + return m_luaRoot; +} + bool UniverseClient::reloadPlayer(Json const& data, Uuid const&, bool resetInterfaces, bool showIndicator) { auto player = mainPlayer(); bool playerInWorld = player->inWorld(); diff --git a/source/game/StarUniverseClient.hpp b/source/game/StarUniverseClient.hpp index 3a3860d..9452cf6 100644 --- a/source/game/StarUniverseClient.hpp +++ b/source/game/StarUniverseClient.hpp @@ -89,6 +89,7 @@ public: void setLuaCallbacks(String const& groupName, LuaCallbacks const& callbacks); void startLua(); void stopLua(); + LuaRootPtr luaRoot(); bool reloadPlayer(Json const& data, Uuid const& uuid, bool resetInterfaces = false, bool showIndicator = false); bool switchPlayer(Uuid const& uuid); diff --git a/source/windowing/StarPane.cpp b/source/windowing/StarPane.cpp index 1511fed..1e20402 100644 --- a/source/windowing/StarPane.cpp +++ b/source/windowing/StarPane.cpp @@ -411,6 +411,18 @@ LuaCallbacks Pane::makePaneCallbacks() { return isDisplayed(); }); + callbacks.registerCallback("hasFocus", [this]() { + hasFocus(); + }); + + callbacks.registerCallback("show", [this]() { + show(); + }); + + callbacks.registerCallback("hide", [this]() { + hide(); + }); + return callbacks; } From e437282d5cf33b01b967151a56c70d8d1603f375 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Wed, 27 Nov 2024 21:29:53 +1100 Subject: [PATCH 070/181] Update StarQuestManager.cpp --- source/game/StarQuestManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/game/StarQuestManager.cpp b/source/game/StarQuestManager.cpp index 4dbc652..2aa22fb 100644 --- a/source/game/StarQuestManager.cpp +++ b/source/game/StarQuestManager.cpp @@ -412,9 +412,9 @@ void QuestManager::update(float dt) { for (auto& questId : expiredQuests) m_quests.remove(questId); - for (auto& q : m_quests) { - if (questValidOnServer(q.second)) - q.second->update(dt); + for (auto& q : m_quests.values()) { + if (questValidOnServer(q)) + q->update(dt); } } From 47de88c373b067dcbd5465185903bb4593b99279 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Wed, 27 Nov 2024 21:29:53 +1100 Subject: [PATCH 071/181] Update StarQuestManager.cpp --- source/game/StarQuestManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/game/StarQuestManager.cpp b/source/game/StarQuestManager.cpp index 4dbc652..2aa22fb 100644 --- a/source/game/StarQuestManager.cpp +++ b/source/game/StarQuestManager.cpp @@ -412,9 +412,9 @@ void QuestManager::update(float dt) { for (auto& questId : expiredQuests) m_quests.remove(questId); - for (auto& q : m_quests) { - if (questValidOnServer(q.second)) - q.second->update(dt); + for (auto& q : m_quests.values()) { + if (questValidOnServer(q)) + q->update(dt); } } From cbde26aebeec3a3cb72cfd6b55c7867d27b8c789 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sat, 30 Nov 2024 09:17:44 +1100 Subject: [PATCH 072/181] move loadstring out of LuaRoot --- source/core/StarLua.cpp | 10 +++++++++- source/game/scripting/StarLuaRoot.cpp | 7 ------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/source/core/StarLua.cpp b/source/core/StarLua.cpp index 5a2effa..91aebab 100644 --- a/source/core/StarLua.cpp +++ b/source/core/StarLua.cpp @@ -537,8 +537,16 @@ LuaContext LuaEngine::createContext() { LuaDetail::shallowCopy(m_state, -1, -2); lua_pop(m_state, 1); + auto context = LuaContext(LuaDetail::LuaHandle(RefPtr(this), popHandle(m_state))); + // Add loadstring + auto handleIndex = context.handleIndex(); + context.set("loadstring", createFunction([this, handleIndex](String const& source, Maybe const& name, Maybe const& env) -> LuaFunction { + String functionName = name ? strf("loadstring: {}", *name) : "loadstring"; + return createFunctionFromSource(env ? env->handleIndex() : handleIndex, source.utf8Ptr(), source.utf8Size(), functionName.utf8Ptr()); + })); + // Then set that environment as the new context environment in the registry. - return LuaContext(LuaDetail::LuaHandle(RefPtr(this), popHandle(m_state))); + return context; } void LuaEngine::collectGarbage(Maybe steps) { diff --git a/source/game/scripting/StarLuaRoot.cpp b/source/game/scripting/StarLuaRoot.cpp index a14d10a..592c24b 100644 --- a/source/game/scripting/StarLuaRoot.cpp +++ b/source/game/scripting/StarLuaRoot.cpp @@ -106,13 +106,6 @@ LuaContext LuaRoot::createContext(StringList const& scriptPaths) { } }); - auto handleIndex = newContext.handleIndex(); - auto engine = m_luaEngine.get(); - newContext.set("loadstring", m_luaEngine->createFunction([engine, handleIndex](String const& source, Maybe const& name, Maybe const& env) -> LuaFunction { - String functionName = name ? strf("loadstring: {}", *name) : "loadstring"; - return engine->createFunctionFromSource(env ? env->handleIndex() : handleIndex, source.utf8Ptr(), source.utf8Size(), functionName.utf8Ptr()); - })); - auto assets = Root::singleton().assets(); for (auto const& scriptPath : scriptPaths) { 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 073/181] 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); From d95eac316405fb100963d47dcd95ccced3462383 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 10 Dec 2024 18:49:29 +1100 Subject: [PATCH 074/181] Input: binds can now make the clipboard available while held, config option to always allow --- source/client/StarClientApplication.cpp | 5 +-- source/frontend/StarClipboardLuaBindings.cpp | 28 +++++++++++---- source/frontend/StarClipboardLuaBindings.hpp | 2 +- source/game/StarInput.cpp | 35 ++++++++++++++++--- source/game/StarInput.hpp | 7 ++++ .../game/scripting/StarInputLuaBindings.cpp | 1 + source/game/scripting/StarRootLuaBindings.cpp | 4 +-- 7 files changed, 65 insertions(+), 17 deletions(-) diff --git a/source/client/StarClientApplication.cpp b/source/client/StarClientApplication.cpp index b4e0955..71bec5d 100644 --- a/source/client/StarClientApplication.cpp +++ b/source/client/StarClientApplication.cpp @@ -543,8 +543,9 @@ void ClientApplication::changeState(MainAppState newState) { m_universeClient->setLuaCallbacks("input", LuaBindings::makeInputCallbacks()); m_universeClient->setLuaCallbacks("voice", LuaBindings::makeVoiceCallbacks()); m_universeClient->setLuaCallbacks("camera", LuaBindings::makeCameraCallbacks(&m_worldPainter->camera())); - if (!m_root->configuration()->get("safeScripts").toBool()) - m_universeClient->setLuaCallbacks("clipboard", LuaBindings::makeClipboardCallbacks(appController())); + + Json alwaysAllow = m_root->configuration()->getPath("safe.alwaysAllowClipboard"); + m_universeClient->setLuaCallbacks("clipboard", LuaBindings::makeClipboardCallbacks(appController(), alwaysAllow && alwaysAllow.toBool())); auto heldScriptPanes = make_shared>(); diff --git a/source/frontend/StarClipboardLuaBindings.cpp b/source/frontend/StarClipboardLuaBindings.cpp index c8a8dfe..037a7dd 100644 --- a/source/frontend/StarClipboardLuaBindings.cpp +++ b/source/frontend/StarClipboardLuaBindings.cpp @@ -1,21 +1,35 @@ #include "StarClipboardLuaBindings.hpp" #include "StarLuaConverters.hpp" +#include "StarInput.hpp" namespace Star { -LuaCallbacks LuaBindings::makeClipboardCallbacks(ApplicationControllerPtr appController) { +LuaCallbacks LuaBindings::makeClipboardCallbacks(ApplicationControllerPtr appController, bool alwaysAllow) { LuaCallbacks callbacks; - callbacks.registerCallback("hasText", [appController]() -> bool { - return appController->hasClipboard(); + auto available = [alwaysAllow]() { return alwaysAllow || Input::singleton().getTag("clipboard") > 0; }; + + callbacks.registerCallback("available", [=]() -> bool { + return available(); }); - callbacks.registerCallback("getText", [appController]() -> Maybe { - return appController->getClipboard(); + callbacks.registerCallback("hasText", [=]() -> bool { + return available() && appController->hasClipboard(); }); - callbacks.registerCallback("setText", [appController](String const& text) { - appController->setClipboard(text); + callbacks.registerCallback("getText", [=]() -> Maybe { + if (!available()) + return {}; + else + return appController->getClipboard(); + }); + + callbacks.registerCallback("setText", [=](String const& text) -> bool { + if (available()) { + appController->setClipboard(text); + return true; + } + return false; }); return callbacks; diff --git a/source/frontend/StarClipboardLuaBindings.hpp b/source/frontend/StarClipboardLuaBindings.hpp index 7515c0b..f38f8d8 100644 --- a/source/frontend/StarClipboardLuaBindings.hpp +++ b/source/frontend/StarClipboardLuaBindings.hpp @@ -6,7 +6,7 @@ namespace Star { namespace LuaBindings { -LuaCallbacks makeClipboardCallbacks(ApplicationControllerPtr appController); +LuaCallbacks makeClipboardCallbacks(ApplicationControllerPtr appController, bool alwaysAllow); } }// namespace Star diff --git a/source/game/StarInput.cpp b/source/game/StarInput.cpp index 7869b52..20e6f18 100644 --- a/source/game/StarInput.cpp +++ b/source/game/StarInput.cpp @@ -223,7 +223,7 @@ Input::BindEntry::BindEntry(String entryId, Json const& config, BindCategory con category = &parentCategory; id = entryId; name = config.getString("name", id); - + tags = jsonToStringList(config.get("tags", JsonArray())); for (Json const& jBind : config.getArray("default", {})) { try { defaultBinds.emplace_back(bindFromJson(jBind)); } @@ -342,6 +342,15 @@ Input::InputState* Input::bindStatePtr(String const& categoryId, String const& b return nullptr; } +Input::InputState& Input::addBindState(BindEntry const* bindEntry) { + auto insertion = m_bindStates.insert(bindEntry, InputState()); + if (insertion.second) { + for (auto& tag : bindEntry->tags) + ++m_activeTags[tag]; + } + return insertion.first->second; +} + Input* Input::s_singleton; Input* Input::singletonPtr() { @@ -393,7 +402,19 @@ void Input::reset() { eraseWhere(m_keyStates, eraseCond); eraseWhere(m_mouseStates, eraseCond); eraseWhere(m_controllerStates, eraseCond); - eraseWhere(m_bindStates, eraseCond); + eraseWhere(m_bindStates, [&](auto& p) { + if (p.second.held) + p.second.reset(); + else { + for (auto& tag : p.first->tags) { + auto find = m_activeTags.find(tag); + if (find != m_activeTags.end() && !--find->second) + m_activeTags.erase(find); + } + return true; + } + return false; + }); } void Input::update() { @@ -415,7 +436,7 @@ bool Input::handleInput(InputEvent const& input, bool gameProcessed) { if (auto binds = m_bindMappings.ptr(keyDown->key)) { for (auto bind : filterBindEntries(*binds, keyDown->mods)) - m_bindStates[bind].press(); + addBindState(bind).press(); } } } @@ -447,7 +468,7 @@ bool Input::handleInput(InputEvent const& input, bool gameProcessed) { if (auto binds = m_bindMappings.ptr(mouseDown->mouseButton)) { for (auto bind : filterBindEntries(*binds, m_pressedMods)) - m_bindStates[bind].press(); + addBindState(bind).press(); } } } @@ -475,7 +496,7 @@ bool Input::handleInput(InputEvent const& input, bool gameProcessed) { if (auto binds = m_bindMappings.ptr(controllerDown->controllerButton)) { for (auto bind : filterBindEntries(*binds, m_pressedMods)) - m_bindStates[bind].press(); + addBindState(bind).press(); } } } @@ -650,4 +671,8 @@ void Input::setBinds(String const& categoryId, String const& bindId, Json const& entry.updated(); } +unsigned Input::getTag(String const& tag) { + return m_activeTags.maybe(tag).value(0); +} + } \ No newline at end of file diff --git a/source/game/StarInput.hpp b/source/game/StarInput.hpp index 113eea9..90a1e05 100644 --- a/source/game/StarInput.hpp +++ b/source/game/StarInput.hpp @@ -61,6 +61,8 @@ public: String name; // The category this entry belongs to. BindCategory const* category; + // Associated string tags that become active when this bind is pressed. + StringList tags; // The default binds. List defaultBinds; @@ -176,6 +178,8 @@ public: void setBinds(String const& categoryId, String const& bindId, Json const& binds); Json getDefaultBinds(String const& categoryId, String const& bindId); Json getBinds(String const& categoryId, String const& bindId); + unsigned getTag(String const& tag); + private: List filterBindEntries(List const& binds, KeyMod mods) const; @@ -184,6 +188,8 @@ private: InputState* bindStatePtr(String const& categoryId, String const& bindId); + InputState& addBindState(BindEntry const* bindEntry); + static Input* s_singleton; // Regenerated on reload. @@ -203,6 +209,7 @@ private: HashMap m_controllerStates; //Bind states HashMap m_bindStates; + StringMap m_activeTags; KeyMod m_pressedMods; bool m_textInputActive; diff --git a/source/game/scripting/StarInputLuaBindings.cpp b/source/game/scripting/StarInputLuaBindings.cpp index 9a99c4a..565e3b9 100644 --- a/source/game/scripting/StarInputLuaBindings.cpp +++ b/source/game/scripting/StarInputLuaBindings.cpp @@ -53,6 +53,7 @@ LuaCallbacks LuaBindings::makeInputCallbacks() { }); callbacks.registerCallbackWithSignature("mousePosition", bind(mem_fn(&Input::mousePosition), input)); + callbacks.registerCallbackWithSignature("getTag", bind(mem_fn(&Input::getTag), input, _1)); return callbacks; } diff --git a/source/game/scripting/StarRootLuaBindings.cpp b/source/game/scripting/StarRootLuaBindings.cpp index e1d7e3e..d87b423 100644 --- a/source/game/scripting/StarRootLuaBindings.cpp +++ b/source/game/scripting/StarRootLuaBindings.cpp @@ -230,7 +230,7 @@ LuaCallbacks LuaBindings::makeRootCallbacks() { }); callbacks.registerCallback("setConfiguration", [root](String const& key, Json const& value) { - if (key == "safeScripts") + if (key == "safeScripts" || key == "safe") throw StarException(strf("Cannot set {}", key)); else root->configuration()->set(key, value); @@ -245,7 +245,7 @@ LuaCallbacks LuaBindings::makeRootCallbacks() { }); callbacks.registerCallback("setConfigurationPath", [root](String const& path, Json const& value) { - if (path.empty() || path.beginsWith("safeScripts")) + if (path.empty() || path.beginsWith("safeScripts") || path.splitAny("[].").get(0) == "safe") throw ConfigurationException(strf("cannot set {}", path)); else root->configuration()->setPath(path, value); From ad508c5322382a1ff36b18ab00bab5790ffd74ed Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 10 Dec 2024 18:50:03 +1100 Subject: [PATCH 075/181] add item copy-paste binds decided against making them bound by default --- assets/opensb/binds/opensb.binds | 15 +++- .../opensb/scripts/opensb/player/commands.lua | 9 ++- .../scripts/opensb/player/copy_paste.lua | 81 +++++++++++++++++++ .../opensb/scripts/opensb/player/player.lua | 2 +- 4 files changed, 101 insertions(+), 6 deletions(-) create mode 100644 assets/opensb/scripts/opensb/player/copy_paste.lua diff --git a/assets/opensb/binds/opensb.binds b/assets/opensb/binds/opensb.binds index 8a4fdc8..d06b6f4 100644 --- a/assets/opensb/binds/opensb.binds +++ b/assets/opensb/binds/opensb.binds @@ -4,7 +4,8 @@ "camera": { "name": "Camera" }, "voice": { "name": "Voice" }, "building": { "name": "Building" }, - "inventory": { "name": "Inventory" } + "inventory": { "name": "Inventory" }, + "editing" : { "name" : "Editing" } }, "name": "Open^#ebd74a;Starbound", "binds": { @@ -48,6 +49,18 @@ "default": [], "group": "building", "name": "Shrink Building Radius" + }, + "editingCopyItemJson": { + "default": [], // [{"type": "key", "value": "C","mods": ["LShift"]}], + "name": "Copy Item in Cursor", + "group": "editing", + "tags" : ["clipboard"] + }, + "editingPasteItemJson": { + "default": [], // [{"type": "key", "value": "V", "mods": ["LShift"]}], + "name": "Paste Item in Cursor", + "group": "editing", + "tags" : ["clipboard"] } } } diff --git a/assets/opensb/scripts/opensb/player/commands.lua b/assets/opensb/scripts/opensb/player/commands.lua index 2b42f48..9696e0d 100644 --- a/assets/opensb/scripts/opensb/player/commands.lua +++ b/assets/opensb/scripts/opensb/player/commands.lua @@ -2,7 +2,7 @@ local module = {} modules.commands = module local commands = {} -local function command(name, func) +local function register(name, func) commands[name] = func end @@ -12,8 +12,7 @@ function module.init() end end - -command("run", function(src) +register("run", function(src) local success, result = pcall(loadstring, src, "/run") if not success then return "^#f00;compile error: " .. result @@ -35,4 +34,6 @@ command("run", function(src) end end end -end) \ No newline at end of file +end) + +module.register = register \ No newline at end of file diff --git a/assets/opensb/scripts/opensb/player/copy_paste.lua b/assets/opensb/scripts/opensb/player/copy_paste.lua new file mode 100644 index 0000000..2a15af4 --- /dev/null +++ b/assets/opensb/scripts/opensb/player/copy_paste.lua @@ -0,0 +1,81 @@ +local module = {} +modules.copy_paste = module + +local commands = modules.commands +local function getItemName(item) + return item.parameters.shortdescription + or root.itemConfig(item.name).config.shortdescription + or item.name +end + +local function popupError(prefix, msg) + sb.logError("%s: %s", prefix, msg) + msg = #msg > 80 and msg:sub(1, 80) .. "..." or msg + local findNewLine = msg:find("\n", 1, true) + interface.queueMessage("^#f00;error:^reset; " .. (findNewLine and msg:sub(1, findNewLine - 1) or msg), 7) +end + +local function getClipboardText() + local text = clipboard.hasText() and clipboard.getText() + return text and text:sub(1, 1) == "{" and text or nil +end + +local function copyItem() + local item = player.swapSlotItem() or player.primaryHandItem() or player.altHandItem() + if not item then return end + + clipboard.setText(sb.printJson(item, 2)) + local message = string.format("Copied ^cyan;%s^reset; to clipboard", getItemName(item)) + interface.queueMessage(message, 4, 0.5) +end + +local function pasteItem() + if player.swapSlotItem() then return end + local data = getClipboardText() + if not data then return end + + local success, result = pcall(sb.parseJson, data) + if not success then + popupError("Error parsing clipboard item", result) + else + local success, err = pcall(player.setSwapSlotItem, result) + if not success then popupError("Error loading clipboard item", err) + else + local message = string.format("Pasted ^cyan;%s^reset; from clipboard", getItemName(result)) + interface.queueMessage(message, 4, 0.5) + end + end +end + +function module.update() + if input.bindDown("opensb", "editingCopyItemJson") then + copyItem() + end + + if input.bindDown("opensb", "editingPasteItemJson") then + pasteItem() + end +end + +commands.register("exportplayer", function() + if not clipboard.available() then + return "Clipboard unavailable" + end + local success, text = pcall(sb.printJson, player.save(), 2) + if not success then return text end + clipboard.setText(text) + return "Exported player to clipboard" +end) + +commands.register("importplayer", function() + local data = getClipboardText() + if not data then return "Clipboard does not contain JSON" end + + local success, result = pcall(sb.parseJson, data) + if not success then + return "Error parsing player: " .. result + else + success, result = pcall(player.load, result) + return success and "Loaded player from clipboard" or "Error loading player: " .. result + end +end) \ No newline at end of file diff --git a/assets/opensb/scripts/opensb/player/player.lua b/assets/opensb/scripts/opensb/player/player.lua index 05cbfb9..7670595 100644 --- a/assets/opensb/scripts/opensb/player/player.lua +++ b/assets/opensb/scripts/opensb/player/player.lua @@ -1,2 +1,2 @@ require "/scripts/opensb/util/modules.lua" -modules("/scripts/opensb/player/", {"commands"}) \ No newline at end of file +modules("/scripts/opensb/player/", {"commands", "copy_paste"}) \ No newline at end of file From a52c213ebef8cd2ba80e47a797f8bf3215e4f61a Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 10 Dec 2024 19:48:16 +1100 Subject: [PATCH 076/181] Update bindings.lua --- assets/opensb/interface/opensb/bindings/bindings.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/opensb/interface/opensb/bindings/bindings.lua b/assets/opensb/interface/opensb/bindings/bindings.lua index cafcc15..32c19e8 100644 --- a/assets/opensb/interface/opensb/bindings/bindings.lua +++ b/assets/opensb/interface/opensb/bindings/bindings.lua @@ -35,7 +35,7 @@ local function finishBind(a, b) if (type(a) == "table") then snareFinished(a) else - snareFinished{ type = a, value = b, mods = getMods(value) } + snareFinished{ type = a, value = b, mods = getMods(b) } for i, mod in ipairs(mods) do mod.active = false end From 65741d697277e3b5e2f4d8c2d77d06316ec6948c Mon Sep 17 00:00:00 2001 From: SilverSokolova <80606782+SilverSokolova@users.noreply.github.com> Date: Tue, 10 Dec 2024 23:35:51 -0600 Subject: [PATCH 077/181] Update player.md --- doc/lua/player.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/doc/lua/player.md b/doc/lua/player.md index f281bad..fd8ebd4 100644 --- a/doc/lua/player.md +++ b/doc/lua/player.md @@ -527,9 +527,3 @@ Returns uuid, type, and orbits for all system objects in the specified system; #### `List` player.collectables(`String` collectionName) Returns a list of names of the collectables the player has unlocked in the specified collection. - ---- - -#### `List` player.teamMembers() - -Returns an array, each entry being a table with `name`, `uuid`, `entity`, `healthPercentage` and `energyPercentage` From 341a9a3556cf47c21a6d1776d66f0708b873de01 Mon Sep 17 00:00:00 2001 From: SilverSokolova <80606782+SilverSokolova@users.noreply.github.com> Date: Wed, 11 Dec 2024 00:18:08 -0600 Subject: [PATCH 078/181] Update openstarbound.md --- doc/lua/openstarbound.md | 80 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/doc/lua/openstarbound.md b/doc/lua/openstarbound.md index d520705..4d948bf 100644 --- a/doc/lua/openstarbound.md +++ b/doc/lua/openstarbound.md @@ -78,9 +78,11 @@ With metadata: Returns a table, key/value being source path/metadata. #### `Image` root.assetImage(`String` image) -#### `Json` root.assetFrames(`String` path) +Returns an image. -*TODO* +#### `Json` root.assetFrames(`String` imagePath) + +Returns an array containing a `file` (the frames file used for the image) and `frames` (the frame data of the image). #### `JsonArray` root.assetPatches(`String` asset) @@ -132,7 +134,7 @@ Sets the HUD's visibility. Returns the HUD's visibility. #### `PaneId` interface.bindRegisteredPane(`string` paneName) -Binds a registered pane (defined in `/source/frontend/StarMainInterfaceTypes`) to a Lua value, which can then call functions on that pane. +Binds a registered pane (defined in `/source/frontend/StarMainInterfaceTypes`) to a Lua value, which can then call widget functions on that pane.
Panes EscapeDialog
Inventory
@@ -171,6 +173,74 @@ TODO Returns the scale used for interfaces. +--- + +# World + +The world table now contains extra bindings. + +--- + +#### `bool` world.isServer() + +Returns whether the script is running on the server or client. + +--- + +#### `bool` world.isClient() + +Returns whether the script is running on the server or client. + +--- + +The following additional world bindings are available only for scripts running on the client. + +--- + +#### `entityId` world.mainPlayer() + +Returns the entity ID of the player hosting the world. + +--- + +#### `Vec2F` world.entityAimPosition(`entityId` entityId) + +Returns the current cursor aim position of the specified entity. + +--- + +#### `bool` world.inWorld() + +Returns whether any players are in the world. + +--- + +The following additional world bindings are available only for scripts running on the server. + +--- + +#### `void` world.setExpiryTime(`float` expiryTime) + +Sets the amount of time to persist a ephemeral world when it is inactive. + +--- + +#### `string` world.id() + +Returns a `String` representation of the world's id. + +--- + +#### `?` world.callScriptContext(`?` ?) + +TODO + +--- + +#### `?` world.sendPacket(`?` ?) + +? + --- # Player @@ -490,3 +560,7 @@ teleportIn
teleportOut
--- + +#### `List` player.teamMembers() + +Returns an array, each entry being a table with `name`, `uuid`, `entity`, `healthPercentage` and `energyPercentage` From 54647362a079f9da8e49dda35fdc61920cbe02e4 Mon Sep 17 00:00:00 2001 From: SilverSokolova <80606782+SilverSokolova@users.noreply.github.com> Date: Wed, 18 Dec 2024 01:47:22 -0600 Subject: [PATCH 079/181] Update StarCraftingInterface.cpp --- source/frontend/StarCraftingInterface.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/frontend/StarCraftingInterface.cpp b/source/frontend/StarCraftingInterface.cpp index 34e0265..d3f2259 100644 --- a/source/frontend/StarCraftingInterface.cpp +++ b/source/frontend/StarCraftingInterface.cpp @@ -41,6 +41,7 @@ CraftingPane::CraftingPane(WorldClientPtr worldClient, PlayerPtr player, Json co m_settings = jsonMerge(assets->json("/interface/windowconfig/crafting.config:default"), jsonMerge(assets->fetchJson(baseConfig), settings)); + m_maxSpinCount = m_settings.get("maxSpinCount", 1000); m_filter = StringSet::from(jsonToStringList(m_settings.get("filter", JsonArray()))); GuiReader reader; @@ -752,14 +753,14 @@ List CraftingPane::determineRecipes() { int CraftingPane::maxCraft() { if (m_player->isAdmin()) - return 1000; + return m_maxSpinCount; auto itemDb = Root::singleton().itemDatabase(); int res = 0; if (m_guiList->selectedItem() != NPos && m_guiList->selectedItem() < m_recipes.size()) { HashMap normalizedBag = m_player->inventory()->availableItems(); auto selectedRecipe = recipeFromSelectedWidget(); res = itemDb->maxCraftableInBag(normalizedBag, m_player->inventory()->availableCurrencies(), selectedRecipe); - res = std::min(res, 1000); + res = std::min(res, m_maxSpinCount); } return res; } From de642ab8bfa00b35a9a56ec13a919e145ce6608c Mon Sep 17 00:00:00 2001 From: SilverSokolova <80606782+SilverSokolova@users.noreply.github.com> Date: Wed, 18 Dec 2024 01:47:58 -0600 Subject: [PATCH 080/181] Add maxSpinCount --- source/frontend/StarCraftingInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/frontend/StarCraftingInterface.cpp b/source/frontend/StarCraftingInterface.cpp index d3f2259..3e6b679 100644 --- a/source/frontend/StarCraftingInterface.cpp +++ b/source/frontend/StarCraftingInterface.cpp @@ -41,8 +41,8 @@ CraftingPane::CraftingPane(WorldClientPtr worldClient, PlayerPtr player, Json co m_settings = jsonMerge(assets->json("/interface/windowconfig/crafting.config:default"), jsonMerge(assets->fetchJson(baseConfig), settings)); - m_maxSpinCount = m_settings.get("maxSpinCount", 1000); m_filter = StringSet::from(jsonToStringList(m_settings.get("filter", JsonArray()))); + m_maxSpinCount = m_settings.get("maxSpinCount", 1000); GuiReader reader; reader.registerCallback("spinCount.up", [=](Widget*) { From e875d5fccd1f5eb166c019bf2700b4ba8a6a2324 Mon Sep 17 00:00:00 2001 From: SilverSokolova <80606782+SilverSokolova@users.noreply.github.com> Date: Wed, 18 Dec 2024 01:49:23 -0600 Subject: [PATCH 081/181] Allow changing maxBuyCount --- source/frontend/StarMerchantInterface.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/frontend/StarMerchantInterface.cpp b/source/frontend/StarMerchantInterface.cpp index 51bccb6..166f996 100644 --- a/source/frontend/StarMerchantInterface.cpp +++ b/source/frontend/StarMerchantInterface.cpp @@ -38,6 +38,8 @@ MerchantPane::MerchantPane( m_itemBag = make_shared(m_settings.getUInt("sellContainerSize")); + m_maxBuyCount = m_settings.getUInt("maxBuyCount"); + GuiReader reader; reader.registerCallback("spinCount.up", [=](Widget*) { if (m_selectedIndex != NPos) { @@ -360,8 +362,8 @@ int MerchantPane::maxBuyCount() { auto assets = Root::singleton().assets(); auto unitPrice = selected->data().toUInt(); if (unitPrice == 0) - return 1000; - return min(1000, (int)floor(m_player->currency("money") / unitPrice)); + return m_maxBuyCount; + return min(m_maxBuyCount, (int)floor(m_player->currency("money") / unitPrice)); } else { return 0; } From 476bdc619c6e9bc68307b5be7ff6c4dd2762bf63 Mon Sep 17 00:00:00 2001 From: SilverSokolova <80606782+SilverSokolova@users.noreply.github.com> Date: Wed, 18 Dec 2024 01:49:41 -0600 Subject: [PATCH 082/181] Update StarCraftingInterface.cpp --- source/frontend/StarCraftingInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/frontend/StarCraftingInterface.cpp b/source/frontend/StarCraftingInterface.cpp index 3e6b679..f1c136d 100644 --- a/source/frontend/StarCraftingInterface.cpp +++ b/source/frontend/StarCraftingInterface.cpp @@ -42,7 +42,7 @@ CraftingPane::CraftingPane(WorldClientPtr worldClient, PlayerPtr player, Json co jsonMerge(assets->fetchJson(baseConfig), settings)); m_filter = StringSet::from(jsonToStringList(m_settings.get("filter", JsonArray()))); - m_maxSpinCount = m_settings.get("maxSpinCount", 1000); + m_maxSpinCount = m_settings.getInt("maxSpinCount", 1000); GuiReader reader; reader.registerCallback("spinCount.up", [=](Widget*) { From 79e2c90ee058c96e564c8c19af43f6114546d787 Mon Sep 17 00:00:00 2001 From: SilverSokolova <80606782+SilverSokolova@users.noreply.github.com> Date: Wed, 18 Dec 2024 01:50:23 -0600 Subject: [PATCH 083/181] Update StarCraftingInterface.cpp --- source/frontend/StarCraftingInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/frontend/StarCraftingInterface.cpp b/source/frontend/StarCraftingInterface.cpp index f1c136d..c44ad2b 100644 --- a/source/frontend/StarCraftingInterface.cpp +++ b/source/frontend/StarCraftingInterface.cpp @@ -42,7 +42,7 @@ CraftingPane::CraftingPane(WorldClientPtr worldClient, PlayerPtr player, Json co jsonMerge(assets->fetchJson(baseConfig), settings)); m_filter = StringSet::from(jsonToStringList(m_settings.get("filter", JsonArray()))); - m_maxSpinCount = m_settings.getInt("maxSpinCount", 1000); + m_maxSpinCount = m_settings.getUInt("maxSpinCount", 1000); GuiReader reader; reader.registerCallback("spinCount.up", [=](Widget*) { From a57347c9b10637fc07a88c7ecdfcec5b59ba1498 Mon Sep 17 00:00:00 2001 From: SilverSokolova <80606782+SilverSokolova@users.noreply.github.com> Date: Wed, 18 Dec 2024 01:50:56 -0600 Subject: [PATCH 084/181] Update StarMerchantInterface.cpp --- source/frontend/StarMerchantInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/frontend/StarMerchantInterface.cpp b/source/frontend/StarMerchantInterface.cpp index 166f996..178b645 100644 --- a/source/frontend/StarMerchantInterface.cpp +++ b/source/frontend/StarMerchantInterface.cpp @@ -38,7 +38,7 @@ MerchantPane::MerchantPane( m_itemBag = make_shared(m_settings.getUInt("sellContainerSize")); - m_maxBuyCount = m_settings.getUInt("maxBuyCount"); + m_maxBuyCount = m_settings.getUInt("maxBuyCount", 1000); GuiReader reader; reader.registerCallback("spinCount.up", [=](Widget*) { From 41cb7dfde4266ad9aef5de777cd903269d492c41 Mon Sep 17 00:00:00 2001 From: SilverSokolova <80606782+SilverSokolova@users.noreply.github.com> Date: Wed, 18 Dec 2024 01:57:19 -0600 Subject: [PATCH 085/181] Update StarCraftingInterface.hpp --- source/frontend/StarCraftingInterface.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/frontend/StarCraftingInterface.hpp b/source/frontend/StarCraftingInterface.hpp index 58dd022..f422406 100644 --- a/source/frontend/StarCraftingInterface.hpp +++ b/source/frontend/StarCraftingInterface.hpp @@ -69,6 +69,8 @@ private: StringSet m_filter; + int m_maxSpinCount; + int m_recipeAutorefreshCooldown; HashMap m_itemCache; From a362aa867a3802fe27ddf52c32e809a3cc750f23 Mon Sep 17 00:00:00 2001 From: SilverSokolova <80606782+SilverSokolova@users.noreply.github.com> Date: Wed, 18 Dec 2024 01:57:51 -0600 Subject: [PATCH 086/181] Update StarMerchantInterface.hpp --- source/frontend/StarMerchantInterface.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/frontend/StarMerchantInterface.hpp b/source/frontend/StarMerchantInterface.hpp index b717a61..967a2ce 100644 --- a/source/frontend/StarMerchantInterface.hpp +++ b/source/frontend/StarMerchantInterface.hpp @@ -76,6 +76,7 @@ private: ItemBagPtr m_itemBag; int m_buyCount; + int m_maxBuyCount; }; } From 621166242be1d2e562a7f1b347000c0fd03d3c45 Mon Sep 17 00:00:00 2001 From: SilverSokolova <80606782+SilverSokolova@users.noreply.github.com> Date: Wed, 18 Dec 2024 02:24:50 -0600 Subject: [PATCH 087/181] Update StarMerchantInterface.cpp --- source/frontend/StarMerchantInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/frontend/StarMerchantInterface.cpp b/source/frontend/StarMerchantInterface.cpp index 178b645..7acd234 100644 --- a/source/frontend/StarMerchantInterface.cpp +++ b/source/frontend/StarMerchantInterface.cpp @@ -38,7 +38,7 @@ MerchantPane::MerchantPane( m_itemBag = make_shared(m_settings.getUInt("sellContainerSize")); - m_maxBuyCount = m_settings.getUInt("maxBuyCount", 1000); + m_maxBuyCount = assets->json("/interface/windowconfig/crafting.config:default").getUInt("maxSpinCount", 1000); GuiReader reader; reader.registerCallback("spinCount.up", [=](Widget*) { From ee918cb476391add2121c32ba5b294cdeaafa6dd Mon Sep 17 00:00:00 2001 From: SilverSokolova <80606782+SilverSokolova@users.noreply.github.com> Date: Wed, 18 Dec 2024 02:26:43 -0600 Subject: [PATCH 088/181] Update crafting.config.patch --- .../interface/windowconfig/crafting.config.patch | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/assets/opensb/interface/windowconfig/crafting.config.patch b/assets/opensb/interface/windowconfig/crafting.config.patch index 0728507..9febcd4 100644 --- a/assets/opensb/interface/windowconfig/crafting.config.patch +++ b/assets/opensb/interface/windowconfig/crafting.config.patch @@ -4,7 +4,11 @@ // Disables the crafting timer if true. "disableTimer" : false, - // This is only used if the crafting timer is enabled. - // This is how many crafts are ran when the crafting timer wraps. - "craftCount" : 1 -} } \ No newline at end of file + // This is only used if the crafting timer is enabled. + // This is how many crafts are ran when the crafting timer wraps. + "craftCount" : 1, + + // This is how many of any item can be crafted at once. + // This is also used by merchants. + "maxSpinCount" : 9999 +} } From 28a8b54f43f10fde8c09f6efe91d1c1b3b09d5d4 Mon Sep 17 00:00:00 2001 From: SilverSokolova <80606782+SilverSokolova@users.noreply.github.com> Date: Wed, 18 Dec 2024 02:42:16 -0600 Subject: [PATCH 089/181] Update StarMerchantInterface.cpp --- source/frontend/StarMerchantInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/frontend/StarMerchantInterface.cpp b/source/frontend/StarMerchantInterface.cpp index 7acd234..196dba1 100644 --- a/source/frontend/StarMerchantInterface.cpp +++ b/source/frontend/StarMerchantInterface.cpp @@ -38,7 +38,7 @@ MerchantPane::MerchantPane( m_itemBag = make_shared(m_settings.getUInt("sellContainerSize")); - m_maxBuyCount = assets->json("/interface/windowconfig/crafting.config:default").getUInt("maxSpinCount", 1000); + m_maxBuyCount = m_settings.getUInt("maxSpinCount", assets->json("/interface/windowconfig/crafting.config:default").getUInt("maxSpinCount", 1000)); GuiReader reader; reader.registerCallback("spinCount.up", [=](Widget*) { From fa81726902facdee92adf106251aca64c914221a Mon Sep 17 00:00:00 2001 From: SilverSokolova <80606782+SilverSokolova@users.noreply.github.com> Date: Wed, 18 Dec 2024 13:58:06 -0600 Subject: [PATCH 090/181] Delete assets/opensb/interface/merchant directory --- assets/opensb/interface/merchant/shine.png | Bin 866 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 assets/opensb/interface/merchant/shine.png diff --git a/assets/opensb/interface/merchant/shine.png b/assets/opensb/interface/merchant/shine.png deleted file mode 100644 index 639bae9277dc750383ed462bd9dbc1db94943126..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 866 zcmeAS@N?(olHy`uVBq!ia0vp^I~f=l1v%J&EcK~u*$fQKnw~C>Ar-gYUfRfcz=4P5 zp#H<(`C;egN}tIRTgRArZerZoGk;&#xMx1tkj-0gVJnlxizr5!qNk0`>qHMIhRazz zImO%_Q~6+mHa|$zd7VwciK*;-mJh^>82NTGw8u0!>m5)Oe=vc&-~=NIkJaJ{lT6V8 z-XfSZM1T>fmko?STF}LSG6-RiUN{2U(ZF4BfYBTYvBxwp>m6WZzr%n)G6jr$I~dqy z3Yd}50al9#Ofm%rc##m}z!<2(g6Tr2^BDOo9 Date: Wed, 18 Dec 2024 13:59:10 -0600 Subject: [PATCH 091/181] Create merchant.config.patch --- .../interface/windowconfig/merchant.config.patch | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 assets/opensb/interface/windowconfig/merchant.config.patch diff --git a/assets/opensb/interface/windowconfig/merchant.config.patch b/assets/opensb/interface/windowconfig/merchant.config.patch new file mode 100644 index 0000000..fd483c2 --- /dev/null +++ b/assets/opensb/interface/windowconfig/merchant.config.patch @@ -0,0 +1,12 @@ +[ + { + "op" : "test", + "path" : "/paneLayout/bgShine/position/1", + "value" : -12 + }, + { + "op" : "replace", + "path" : "/paneLayout/bgShine/position/1", + "value" : -19 + } +] From 0a035226d881cd0654b38cbcdfaae22aaac79b28 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:02:08 -0800 Subject: [PATCH 092/181] Update client.config.patch --- assets/opensb/client.config.patch | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/opensb/client.config.patch b/assets/opensb/client.config.patch index 619a767..7bd18d6 100644 --- a/assets/opensb/client.config.patch +++ b/assets/opensb/client.config.patch @@ -10,5 +10,6 @@ "scissor" : false, "letterbox" : false }, - "postProcessLayers": [] + "postProcessLayers": [], + "postProcessGroups": {} } From 7253f4093215754898c05da32af154f08de88b1a Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:03:32 -0800 Subject: [PATCH 093/181] Update build.yml --- .github/workflows/build.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 33ba3a5..925c2a3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,14 +3,6 @@ name: Build on: workflow_dispatch: - push: - branches: - - "*" - - pull_request: - branches: - - "*" - jobs: build_windows: name: Build OpenStarbound Windows x64 @@ -232,4 +224,4 @@ jobs: uses: actions/upload-artifact@v4 with: name: OpenStarbound-macOS-Silicon - path: dist/* \ No newline at end of file + path: dist/* From 209d89a07df54ee63754fc3d8137f1775a4cce17 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:05:55 -0800 Subject: [PATCH 094/181] Update StarClientApplication.cpp --- source/client/StarClientApplication.cpp | 41 ++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/source/client/StarClientApplication.cpp b/source/client/StarClientApplication.cpp index 71bec5d..7d8d321 100644 --- a/source/client/StarClientApplication.cpp +++ b/source/client/StarClientApplication.cpp @@ -434,6 +434,8 @@ void ClientApplication::getAudioData(int16_t* sampleData, size_t frameCount) { } } +auto postProcessGroupsRoot = "postProcessGroups"; + void ClientApplication::renderReload() { auto assets = m_root->assets(); auto renderer = Application::renderer(); @@ -464,18 +466,55 @@ void ClientApplication::renderReload() { loadEffectConfig("world"); + // define post process groups and set them to be enabled/disabled based on config + + auto config = m_root->configuration(); + if (!config->get(postProcessGroupsRoot).isType(Json::Type::Object)) + config->set(postProcessGroupsRoot, JsonObject()); + auto groupsConfig = config->get(postProcessGroupsRoot); + + m_postProcessGroups.clear(); + auto postProcessGroups = assets->json("/client.config:postProcessGroups").toObject(); + for (auto& pair : postProcessGroups) { + auto name = pair.first; + auto groupConfig = groupsConfig.opt(name); + auto def = pair.second.getBool("enabledDefault",true); + if (!groupConfig) + config->setPath(strf("{}.{}", postProcessGroupsRoot, name),JsonObject()); + m_postProcessGroups.add(name,PostProcessGroup{ groupConfig ? groupConfig.value().getBool("enabled", def) : def }); + } + + // define post process layers and optionally assign them to groups m_postProcessLayers.clear(); auto postProcessLayers = assets->json("/client.config:postProcessLayers").toArray(); for (auto& layer : postProcessLayers) { auto effects = jsonToStringList(layer.getArray("effects")); for (auto& effect : effects) loadEffectConfig(effect); - m_postProcessLayers.append(PostProcessLayer{ std::move(effects), (unsigned)layer.getUInt("passes", 1) }); + PostProcessGroup* group = nullptr; + auto gname = layer.optString("group"); + if (gname) { + group = &m_postProcessGroups.get(gname.value()); + } + m_postProcessLayers.append(PostProcessLayer{ std::move(effects), (unsigned)layer.getUInt("passes", 1), group }); } loadEffectConfig("interface"); } +void ClientApplication::setPostProcessGroupEnabled(String group, bool enabled, Maybe save) { + m_postProcessGroups.get(group).enabled = enabled; + if (save && save.value()) + m_root->configuration()->setPath(strf("{}.{}.enabled", postProcessGroupsRoot, group),enabled); +} +bool ClientApplication::postProcessGroupEnabled(String group) { + return m_postProcessGroups.get(group).enabled; +} + +Json ClientApplication::postProcessGroups() { + return m_root->assets()->json("/client.config:postProcessGroups"); +} + void ClientApplication::changeState(MainAppState newState) { MainAppState oldState = m_state; m_state = newState; From e009a15ba7a851625627852f3fd8219e9ba962b5 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:06:56 -0800 Subject: [PATCH 095/181] Update StarClientApplication.cpp --- source/client/StarClientApplication.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/client/StarClientApplication.cpp b/source/client/StarClientApplication.cpp index 7d8d321..e22093c 100644 --- a/source/client/StarClientApplication.cpp +++ b/source/client/StarClientApplication.cpp @@ -24,6 +24,7 @@ #include "StarVoiceLuaBindings.hpp" #include "StarCameraLuaBindings.hpp" #include "StarClipboardLuaBindings.hpp" +#include "StarRenderingLuaBindings.hpp" #if defined STAR_SYSTEM_WINDOWS #include @@ -582,6 +583,7 @@ void ClientApplication::changeState(MainAppState newState) { m_universeClient->setLuaCallbacks("input", LuaBindings::makeInputCallbacks()); m_universeClient->setLuaCallbacks("voice", LuaBindings::makeVoiceCallbacks()); m_universeClient->setLuaCallbacks("camera", LuaBindings::makeCameraCallbacks(&m_worldPainter->camera())); + m_universeClient->setLuaCallbacks("renderer", LuaBindings::makeRenderingCallbacks(this)); Json alwaysAllow = m_root->configuration()->getPath("safe.alwaysAllowClipboard"); m_universeClient->setLuaCallbacks("clipboard", LuaBindings::makeClipboardCallbacks(appController(), alwaysAllow && alwaysAllow.toBool())); From 226ff4e2788bb8f5c04eae629b777cf9b44112d7 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:07:58 -0800 Subject: [PATCH 096/181] Update StarClientApplication.hpp --- source/client/StarClientApplication.hpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source/client/StarClientApplication.hpp b/source/client/StarClientApplication.hpp index 840dc9a..323f2b7 100644 --- a/source/client/StarClientApplication.hpp +++ b/source/client/StarClientApplication.hpp @@ -18,6 +18,11 @@ STAR_CLASS(Input); STAR_CLASS(Voice); class ClientApplication : public Application { +public: + void setPostProcessGroupEnabled(String group, bool enabled, Maybe save); + bool postProcessGroupEnabled(String group); + Json postProcessGroups(); + protected: virtual void startup(StringList const& cmdLineArgs) override; virtual void shutdown() override; @@ -53,9 +58,14 @@ private: String password; }; + struct PostProcessGroup { + bool enabled; + }; + struct PostProcessLayer { List effects; unsigned passes; + PostProcessGroup* group; }; void renderReload(); @@ -104,6 +114,7 @@ private: WorldRenderData m_renderData; MainInterfacePtr m_mainInterface; + StringMap m_postProcessGroups; List m_postProcessLayers; // Valid if main app state == SinglePlayer From b7aa4f6da681752eeba59750715baa01aa3654e0 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:09:19 -0800 Subject: [PATCH 097/181] Add files via upload --- source/client/StarRenderingLuaBindings.cpp | 21 +++++++++++++++++++++ source/client/StarRenderingLuaBindings.hpp | 13 +++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 source/client/StarRenderingLuaBindings.cpp create mode 100644 source/client/StarRenderingLuaBindings.hpp diff --git a/source/client/StarRenderingLuaBindings.cpp b/source/client/StarRenderingLuaBindings.cpp new file mode 100644 index 0000000..4c9e7a2 --- /dev/null +++ b/source/client/StarRenderingLuaBindings.cpp @@ -0,0 +1,21 @@ +#include "StarRenderingLuaBindings.hpp" +#include "StarLuaConverters.hpp" +#include "StarClientApplication.hpp" + +namespace Star { + +LuaCallbacks LuaBindings::makeRenderingCallbacks(ClientApplication* app) { + LuaCallbacks callbacks; + + // if the last argument is defined and true, this change will also be saved to starbound.config and read on next game start, use for things such as an interface that does this + callbacks.registerCallbackWithSignature>("setPostProcessGroupEnabled", bind(mem_fn(&ClientApplication::setPostProcessGroupEnabled), app, _1, _2, _3)); + callbacks.registerCallbackWithSignature("postProcessGroupEnabled", bind(mem_fn(&ClientApplication::postProcessGroupEnabled), app, _1)); + + // not entirely necessary (root.assetJson can achieve the same purpose) but may as well + callbacks.registerCallbackWithSignature("postProcessGroups", bind(mem_fn(&ClientApplication::postProcessGroups), app)); + + return callbacks; +} + + +} diff --git a/source/client/StarRenderingLuaBindings.hpp b/source/client/StarRenderingLuaBindings.hpp new file mode 100644 index 0000000..68e709f --- /dev/null +++ b/source/client/StarRenderingLuaBindings.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include "StarLua.hpp" + +namespace Star { + +STAR_CLASS(ClientApplication); + +namespace LuaBindings { + LuaCallbacks makeRenderingCallbacks(ClientApplication* app); +} + +} From 1d80822543c5f7cf949385a4a920538027f8f4ea Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:10:07 -0800 Subject: [PATCH 098/181] Update CMakeLists.txt --- source/client/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/client/CMakeLists.txt b/source/client/CMakeLists.txt index 57b8231..a6773d3 100644 --- a/source/client/CMakeLists.txt +++ b/source/client/CMakeLists.txt @@ -12,10 +12,12 @@ INCLUDE_DIRECTORIES ( SET (star_client_HEADERS StarClientApplication.hpp + StarRenderingLuaBindings.hpp ) SET (star_client_SOURCES StarClientApplication.cpp + StarRenderingLuaBindings.cpp ) IF (STAR_SYSTEM_WINDOWS) @@ -37,4 +39,4 @@ IF(UNIX) set_target_properties (starbound PROPERTIES LINK_FLAGS "-Wl,-rpath,'$ORIGIN'") ENDIF() -TARGET_LINK_LIBRARIES (starbound ${STAR_EXT_LIBS} ${STAR_EXT_GUI_LIBS}) \ No newline at end of file +TARGET_LINK_LIBRARIES (starbound ${STAR_EXT_LIBS} ${STAR_EXT_GUI_LIBS}) From 2ffe1146866193998e65129decc378a9665fc3a9 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:13:34 -0800 Subject: [PATCH 099/181] Update StarClientApplication.cpp --- source/client/StarClientApplication.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/client/StarClientApplication.cpp b/source/client/StarClientApplication.cpp index e22093c..81b217f 100644 --- a/source/client/StarClientApplication.cpp +++ b/source/client/StarClientApplication.cpp @@ -406,10 +406,12 @@ void ClientApplication::render() { auto size = Vec2F(renderer->screenSize()); auto quad = renderFlatRect(RectF::withSize(size / -2, size), Vec4B::filled(0), 0.0f); for (auto& layer : m_postProcessLayers) { - for (unsigned i = 0; i < layer.passes; i++) { - for (auto& effect : layer.effects) { - renderer->switchEffectConfig(effect); - renderer->render(quad); + if (layer.group ? layer.group->enabled : true) { + for (unsigned i = 0; i < layer.passes; i++) { + for (auto& effect : layer.effects) { + renderer->switchEffectConfig(effect); + renderer->render(quad); + } } } } From 7bc0f942bc3a04df71d0df393f783d645257279b Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:21:32 -0800 Subject: [PATCH 100/181] Update StarMainInterface.cpp --- source/frontend/StarMainInterface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/frontend/StarMainInterface.cpp b/source/frontend/StarMainInterface.cpp index 41eceb7..8468f7f 100644 --- a/source/frontend/StarMainInterface.cpp +++ b/source/frontend/StarMainInterface.cpp @@ -117,7 +117,7 @@ MainInterface::MainInterface(UniverseClientPtr client, WorldPainterPtr painter, m_codexInterface = make_shared(m_client->mainPlayer()); m_paneManager.registerPane(MainInterfacePanes::Codex, PaneLayer::Window, m_codexInterface); - m_optionsMenu = make_shared(&m_paneManager); + m_optionsMenu = make_shared(&m_paneManager,m_client); m_paneManager.registerPane(MainInterfacePanes::Options, PaneLayer::ModalWindow, m_optionsMenu); m_popupInterface = make_shared(); @@ -1604,4 +1604,4 @@ void MainInterface::displayScriptPane(ScriptPanePtr& scriptPane, EntityId source } } -} \ No newline at end of file +} From 096ab486f651d803b8a7f50e448b50e17e907539 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:22:12 -0800 Subject: [PATCH 101/181] Update StarOptionsMenu.hpp --- source/frontend/StarOptionsMenu.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/frontend/StarOptionsMenu.hpp b/source/frontend/StarOptionsMenu.hpp index 4bc36ad..9fde1ac 100644 --- a/source/frontend/StarOptionsMenu.hpp +++ b/source/frontend/StarOptionsMenu.hpp @@ -3,6 +3,7 @@ #include "StarPane.hpp" #include "StarConfiguration.hpp" #include "StarMainInterfaceTypes.hpp" +#include "StarUniverseClient.hpp" namespace Star { @@ -17,7 +18,7 @@ STAR_CLASS(OptionsMenu); class OptionsMenu : public Pane { public: - OptionsMenu(PaneManager* manager); + OptionsMenu(PaneManager* manager, UniverseClientPtr client); virtual void show() override; From 1303f54e30f1d33b5f21b527cff000daf990ba04 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:23:54 -0800 Subject: [PATCH 102/181] Update StarOptionsMenu.cpp --- source/frontend/StarOptionsMenu.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/frontend/StarOptionsMenu.cpp b/source/frontend/StarOptionsMenu.cpp index 0ea1fa1..8253f1f 100644 --- a/source/frontend/StarOptionsMenu.cpp +++ b/source/frontend/StarOptionsMenu.cpp @@ -13,7 +13,7 @@ namespace Star { -OptionsMenu::OptionsMenu(PaneManager* manager) +OptionsMenu::OptionsMenu(PaneManager* manager, UniverseClientPtr client) : m_sfxRange(0, 100), m_musicRange(0, 100), m_paneManager(manager) { auto root = Root::singletonPtr(); auto assets = root->assets(); @@ -90,7 +90,7 @@ OptionsMenu::OptionsMenu(PaneManager* manager) m_voiceSettingsMenu = make_shared(assets->json(config.getString("voiceSettingsPanePath", "/interface/opensb/voicechat/voicechat.config"))); m_modBindingsMenu = make_shared(assets->json(config.getString("bindingsPanePath", "/interface/opensb/bindings/bindings.config"))); m_keybindingsMenu = make_shared(); - m_graphicsMenu = make_shared(); + m_graphicsMenu = make_shared(manager,client); initConfig(); } From e12860ad25ec5c345ff2db209a26b2205953529d Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:26:35 -0800 Subject: [PATCH 103/181] Update StarGraphicsMenu.cpp --- source/frontend/StarGraphicsMenu.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/source/frontend/StarGraphicsMenu.cpp b/source/frontend/StarGraphicsMenu.cpp index efce444..3974453 100644 --- a/source/frontend/StarGraphicsMenu.cpp +++ b/source/frontend/StarGraphicsMenu.cpp @@ -9,10 +9,12 @@ #include "StarButtonWidget.hpp" #include "StarOrderedSet.hpp" #include "StarJsonExtra.hpp" +#include "StarShadersMenu.hpp" namespace Star { -GraphicsMenu::GraphicsMenu() { +GraphicsMenu::GraphicsMenu(PaneManager* manager,UniverseClientPtr client) + : m_paneManager(manager) { GuiReader reader; reader.registerCallback("cancel", [&](Widget*) { @@ -103,10 +105,14 @@ GraphicsMenu::GraphicsMenu() { Root::singleton().configuration()->set("newLighting", checked); syncGui(); }); + reader.registerCallback("showShadersMenu", [=](Widget*) { + displayShaders(); + }); auto assets = Root::singleton().assets(); - Json paneLayout = assets->json("/interface/windowconfig/graphicsmenu.config:paneLayout"); + auto config = assets->json("/interface/windowconfig/graphicsmenu.config"); + Json paneLayout = config.get("paneLayout"); m_interfaceScaleList = jsonToIntList(assets->json("/interface/windowconfig/graphicsmenu.config:interfaceScaleList")); m_resList = jsonToVec2UList(assets->json("/interface/windowconfig/graphicsmenu.config:resolutionList")); @@ -122,6 +128,8 @@ GraphicsMenu::GraphicsMenu() { initConfig(); syncGui(); + + m_shadersMenu = make_shared(assets->json(config.getString("shadersPanePath", "/interface/opensb/shaders/shaders.config")), client); } void GraphicsMenu::show() { @@ -240,6 +248,10 @@ void GraphicsMenu::apply() { } } +void GraphicsMenu::displayShaders() { + m_paneManager->displayPane(PaneLayer::ModalWindow, m_shadersMenu); +} + void GraphicsMenu::applyWindowSettings() { auto configuration = Root::singleton().configuration(); auto appController = GuiContext::singleton().applicationController(); @@ -253,4 +265,4 @@ void GraphicsMenu::applyWindowSettings() { appController->setNormalWindow(jsonToVec2U(configuration->get("windowedResolution"))); } -} \ No newline at end of file +} From 0c4682d304d37e0c634ddf90dc49a0560310c9ab Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:26:59 -0800 Subject: [PATCH 104/181] Update StarGraphicsMenu.hpp --- source/frontend/StarGraphicsMenu.hpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/source/frontend/StarGraphicsMenu.hpp b/source/frontend/StarGraphicsMenu.hpp index 6d03652..c212f71 100644 --- a/source/frontend/StarGraphicsMenu.hpp +++ b/source/frontend/StarGraphicsMenu.hpp @@ -1,14 +1,17 @@ #pragma once #include "StarPane.hpp" +#include "StarMainInterfaceTypes.hpp" +#include "StarUniverseClient.hpp" namespace Star { STAR_CLASS(GraphicsMenu); +STAR_CLASS(ShadersMenu); class GraphicsMenu : public Pane { public: - GraphicsMenu(); + GraphicsMenu(PaneManager* manager,UniverseClientPtr client); void show() override; void dismissed() override; @@ -23,6 +26,8 @@ private: void apply(); void applyWindowSettings(); + + void displayShaders(); List m_resList; List m_interfaceScaleList; @@ -30,6 +35,9 @@ private: List m_cameraSpeedList; JsonObject m_localChanges; + + ShadersMenuPtr m_shadersMenu; + PaneManager* m_paneManager; }; } From bf6969dc7df8a8f979085971d84a870d09528f85 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:28:39 -0800 Subject: [PATCH 105/181] Add files via upload --- source/frontend/StarShadersMenu.cpp | 22 ++++++++++++++++++++++ source/frontend/StarShadersMenu.hpp | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 source/frontend/StarShadersMenu.cpp create mode 100644 source/frontend/StarShadersMenu.hpp diff --git a/source/frontend/StarShadersMenu.cpp b/source/frontend/StarShadersMenu.cpp new file mode 100644 index 0000000..4e15b66 --- /dev/null +++ b/source/frontend/StarShadersMenu.cpp @@ -0,0 +1,22 @@ +#include "StarShadersMenu.hpp" + +namespace Star { + +ShadersMenu::ShadersMenu(Json const& config, UniverseClientPtr client) : BaseScriptPane(config) { + m_client = std::move(client); +} + +void ShadersMenu::show() { + BaseScriptPane::show(); +} + +void ShadersMenu::displayed() { + m_script.setLuaRoot(m_client->luaRoot()); + BaseScriptPane::displayed(); +} + +void ShadersMenu::dismissed() { + BaseScriptPane::dismissed(); +} + +} diff --git a/source/frontend/StarShadersMenu.hpp b/source/frontend/StarShadersMenu.hpp new file mode 100644 index 0000000..9b24b0d --- /dev/null +++ b/source/frontend/StarShadersMenu.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "StarBaseScriptPane.hpp" +#include "StarUniverseClient.hpp" + +namespace Star { + +STAR_CLASS(ShadersMenu); + +class ShadersMenu : public BaseScriptPane { +public: + ShadersMenu(Json const& config, UniverseClientPtr client); + + virtual void show() override; + void displayed() override; + void dismissed() override; + +private: + UniverseClientPtr m_client; +}; + +} From 9cff2ce433b676b10aad43e6304fb0c5216cbb39 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:30:16 -0800 Subject: [PATCH 106/181] Update CMakeLists.txt --- source/frontend/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/frontend/CMakeLists.txt b/source/frontend/CMakeLists.txt index 0934308..b619e90 100644 --- a/source/frontend/CMakeLists.txt +++ b/source/frontend/CMakeLists.txt @@ -55,6 +55,7 @@ SET (star_frontend_HEADERS StarSimpleTooltip.hpp StarSongbookInterface.hpp StarStatusPane.hpp + StarShadersMenu.hpp StarTeleportDialog.hpp StarVoice.hpp StarVoiceLuaBindings.hpp @@ -107,6 +108,7 @@ SET (star_frontend_SOURCES StarSimpleTooltip.cpp StarSongbookInterface.cpp StarStatusPane.cpp + StarShadersMenu.cpp StarTeleportDialog.cpp StarVoice.cpp StarVoiceLuaBindings.cpp @@ -118,4 +120,4 @@ ADD_LIBRARY (star_frontend OBJECT ${star_frontend_SOURCES} ${star_frontend_HEADE IF(STAR_PRECOMPILED_HEADERS) TARGET_PRECOMPILE_HEADERS (star_frontend REUSE_FROM star_core) -ENDIF() \ No newline at end of file +ENDIF() From 8dbbbcb0861583a650d83c8f7e0793eafe972bed Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:33:27 -0800 Subject: [PATCH 107/181] Update graphicsmenu.config.patch.lua --- .../windowconfig/graphicsmenu.config.patch.lua | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/assets/opensb/interface/windowconfig/graphicsmenu.config.patch.lua b/assets/opensb/interface/windowconfig/graphicsmenu.config.patch.lua index 7d7ab44..b17053a 100644 --- a/assets/opensb/interface/windowconfig/graphicsmenu.config.patch.lua +++ b/assets/opensb/interface/windowconfig/graphicsmenu.config.patch.lua @@ -13,6 +13,12 @@ local function shift(thing, x, y) return thing end +local function moveto(thing, otherthing) + thing.position[1] = otherthing.position[1] + thing.position[2] = otherthing.position[2] + return thing +end + -- patch function, called by the game function patch(config) local layout = config.paneLayout @@ -41,10 +47,14 @@ function patch(config) -- Create hardware cursor toggle shift(clone(layout, "multiTextureLabel", "hardwareCursorLabel"), 98, -11).value = "HARDWARE CURSOR" shift(clone(layout, "multiTextureCheckbox", "hardwareCursorCheckbox"), 99, -11) + + -- Create shader menu button + shift(moveto(clone(layout, "accept", "showShadersMenu"), layout.interfaceScaleSlider), 112, -2).caption = "Shaders" + shift(layout.title, 0, 24) shift(layout.resLabel, 0, 28) shift(layout.resSlider, 0, 28) shift(layout.resValueLabel, 0, 28) return config -end \ No newline at end of file +end From 20f0efdcb8af2d7ea2684762e695f460c5d75f34 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:34:58 -0800 Subject: [PATCH 108/181] add shader interface --- .../opensb/interface/opensb/shaders/body.png | Bin 0 -> 743 bytes .../interface/opensb/shaders/categoryname.png | Bin 0 -> 391 bytes .../interface/opensb/shaders/footer.png | Bin 0 -> 163 bytes .../opensb/interface/opensb/shaders/group.png | Bin 0 -> 80 bytes .../interface/opensb/shaders/groupback.png | Bin 0 -> 162 bytes .../interface/opensb/shaders/header.png | Bin 0 -> 4346 bytes .../interface/opensb/shaders/optionname.png | Bin 0 -> 197 bytes .../interface/opensb/shaders/shaders.config | 147 ++++++++++++ .../interface/opensb/shaders/shaders.lua | 219 ++++++++++++++++++ 9 files changed, 366 insertions(+) create mode 100644 assets/opensb/interface/opensb/shaders/body.png create mode 100644 assets/opensb/interface/opensb/shaders/categoryname.png create mode 100644 assets/opensb/interface/opensb/shaders/footer.png create mode 100644 assets/opensb/interface/opensb/shaders/group.png create mode 100644 assets/opensb/interface/opensb/shaders/groupback.png create mode 100644 assets/opensb/interface/opensb/shaders/header.png create mode 100644 assets/opensb/interface/opensb/shaders/optionname.png create mode 100644 assets/opensb/interface/opensb/shaders/shaders.config create mode 100644 assets/opensb/interface/opensb/shaders/shaders.lua diff --git a/assets/opensb/interface/opensb/shaders/body.png b/assets/opensb/interface/opensb/shaders/body.png new file mode 100644 index 0000000000000000000000000000000000000000..272ed29cb23d057e6c369893881c006c880ec096 GIT binary patch literal 743 zcmeAS@N?(olHy`uVBq!ia0y~yV4MJCpWt8vlE*~1KVo2DTIcEF7*cWT?R9IeW(SeB zKyK~jeDD0d%?r&9mvWn|Twl7%fum)HfMS2K*UVS$KaZ73v^};t-`6EV* zcb<8(Z4Pstb6VMBi+Q(BH%Glr63b({6wSC}xhW$96H`M2gMtDB2L}j|%{!!i`ph{l z1%(e=It-Zp94L?RirgM2!P>HY#a6wrhV}d&@A+98?s8IK1Ig}$cnant8t~K@92^(~ z1Q=LY7#JCWh^9QSC2$*P%!7FfVjltCH?9*VzI!bzrhaGtcV1H9sHTU#+rwU90%q`Z L^>bP0l+XkKH!ORL literal 0 HcmV?d00001 diff --git a/assets/opensb/interface/opensb/shaders/categoryname.png b/assets/opensb/interface/opensb/shaders/categoryname.png new file mode 100644 index 0000000000000000000000000000000000000000..3019556043a9c3036ecc8f33573cfd6e6a496beb GIT binary patch literal 391 zcmV;20eJq2P)TrR426xA+w~lrYR=K?AhAJ$B^{{?q_~*;Ie}Sp8R>meCQS0|I7Uyn*Xt$JFbqSU z^Puuf*PQls=CW7C@l8iLUz5LDd(d%HhwiA1YaM;4xzrbC=1>!*T(L&ZIyQCJcVoWi zBU2ySoar1&`5$^!-Hqb>q%$>9+f!=Z3s>({#GgaXas4r~zn+D{+NJS98{#AmUo;fg zyxep?=A)$b63!vrlN?JqR!ZzczEsm05c8YbN%CF%L%uxB8s#<0cQ{iQO>?)TE4?zY z)fughO#Qx`-}cn#=tIpmuEpukIF8>00O*SI(+IJfdS|c^{!i%<&9PV&>!kuH_tP^zyNfJde=?U1Oo%m lA?jUs9EV3M0O$|(?jH(LP24s+jGzDj002ovPDHLkV1ifNxI+K{ literal 0 HcmV?d00001 diff --git a/assets/opensb/interface/opensb/shaders/footer.png b/assets/opensb/interface/opensb/shaders/footer.png new file mode 100644 index 0000000000000000000000000000000000000000..426f8a6352da4b45c41074454618864c15284320 GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0y~yV4MJC^K-BP$x}aOz5`NOo-U3d6}R4AJ;-^$fQQAg ze963!eX~6-oadKJ`p;BsaQ#rO>~Y>R>34;b&xgV5OkMbRg8`S_cOwL#)NNk1w2<7zopr0L4->nE(I) literal 0 HcmV?d00001 diff --git a/assets/opensb/interface/opensb/shaders/group.png b/assets/opensb/interface/opensb/shaders/group.png new file mode 100644 index 0000000000000000000000000000000000000000..66f5cdb3e8491ddf26d0453112042f3ab852c6cc GIT binary patch literal 80 zcmeAS@N?(olHy`uVBq!ia0vp^O+YNb2qYLjU7IBVq{Ka4978H@CI9GW<1;WZSisaS csL~`T#c-iQ`{C`Dh(eH3Pgg&ebxsLQ0KCZ*fdBvi literal 0 HcmV?d00001 diff --git a/assets/opensb/interface/opensb/shaders/groupback.png b/assets/opensb/interface/opensb/shaders/groupback.png new file mode 100644 index 0000000000000000000000000000000000000000..ed838f3cdaa699d9e46ec9aacdf8b3c9c1cc372d GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^O+YNb0VEjyAN!FBq%u8S978H@y`5?()S$q_V$Spa zN_*tbi*sBZ5@fPx85}5_oo4+ib?Fp~Ez4b_HrjETEuP14;_lOR^VaS3JF&FwLwVFr z#+DA-{rgPE<`Lnf|S_DC6y9=C!2r_Lm9A|2h;Pc7Pwa4Ml(fZ;w zav>Wr;75?yhe7Xe(~hE=>sK=DjkbMa)|qGYow=>+yzLua` z|9CmKPnY*~3cD`xi@}|XmSjEjd+eQ7@-&HMB|Mzl>~6lh^Tz8NF3h7>Nxrh~8y%$| z^&RSsYKE3R9avd>96A43x-tF5mxmqAZ!e|%e`YTF;)&NqJ8}qd%@8=vyQDRYIfz!xrBbUc`wuJa%EM`+vHt*R{K2Dw)R@0Cv$7Y zukyS8`pGBVzW2M1m6ax!=B8dps%ynUc}v=NJ2T4Ph>0J!Mz1W44j_9=xLxn>oMAX; zdimnEHsZjhZ(nFaH>JL=d9#PUurz!6KZj~sk#z%Uwv*p|{1oTK%TqK>Z@B$!rlF*v zp8Y|w@7FDdHXTTND*fIzIrp>tgUc2ksn&HYAM9y+^5m)X?xthX+-3Hjoc(z=PgbdM z&)1I}?#}7QPnAF4#aua0Jf3lRJ2-eI%az%@rg6qC+RW$nCEYf&yrytDFRb|D^F`I) zroEOSm2{mr)W8@{99(pL?uKa9_WieaK2xC8bXrbz&wuyGtXFoo{CE9VmP_gAaLU?? zzk9GVv1h~9zOU{dT5@0IZLhxipZnihD84p5WyOM*vO5Yl@Au|R8>slklZe*ON;y#1 zS@XZ@YsmTM{?apB6g7|U%zofp|G7{5`fk|ITpUQA-y$_?PJK`URTmSWy4HABGF&*Q zWBITT=wd+;$__znD`FzcRRJ0GfeImH#|Ao%V5q>`u~MUl^oR~nDHPO8ps0RTF;`#3 zS$S;59a>wAfdD}uvuG?B2t}Bf9aC``I9ALAhN>=dl^t8-@uH5f1W<#{pd)ctOsJ)? zJG7`x;{8maGj9|EzS*%#Sr!?Bh(@Ejs9qPADhSGIwGt#v&@>J`@JL-qW@C6LvP6Lx z!Ek~ICkdh~ghQx;$@;=IvK_t=M-ssx5g!qeU9}Ko zG@&1ih!n#^N)&=fxJKfDs}_XhCGikEHy$t6NCCARo+Cg21fgpLu1ZZ zMjcWdsppJ-8V44O88;YdKW+uA4+lOyYotgM&H1=ED0e6#vmp*BP!L=vKpZQ_lB~sQ zhJh9uHvnM7Sv||*W&r%Gk)%y}pFa-bUP*weWCQV8DNsCw;vo)c&|7fc%$sn79;(Bl zXDOVtS`9`MPtiUKs8Bq|WL-DIvnv0$$A%VvS63 zm29X2!0s_B*D<^B15%(_pU+5{Ot{GmRbU{29%p?}6h^CFPg+d89&nb4=#j8rjl6sVe?d`rS=yV>-wrQYNxpmXo$8efx$5Y65RPVw1!WNgnU$`5ry;xA=R;$%?Dn{l z|CN%Ss3Fd-EqVl+o^?BOi(?;N`k-rO0+sscdkcDRePxTh?VIf_34e0z9^8k0*|>H0 zU|)4h9Oez+nd@C zCp63x)*~;zbl37!WQRtBBqTI6ASjB!;ZJ!RZ2enPleNEh88Tc_b*VP_-v!u5Eomu~ PQli_n%6agv`x^fb1g{X# literal 0 HcmV?d00001 diff --git a/assets/opensb/interface/opensb/shaders/optionname.png b/assets/opensb/interface/opensb/shaders/optionname.png new file mode 100644 index 0000000000000000000000000000000000000000..f7c45002b58b96fe8debb76af4a9e10e8d11992e GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^A3$slHXu1Y@^L7T>hW}O45_&F_SQyDCPxw1i!T#4 zajM-6J9FmE0k@nZ4uUSJjv_8P7t*tscU3iAKDhtl@1;{dJy;(5NaS_IQ6n+Ke#yzt zPq6kh{0#fP b.name end +local function alphabeticalNameSortLesser(a, b) return a.name < b.name end +local sortedGroups = {} +local groups = {} + +local widgetsToGroups = {} +local allSettings = {} + +local function addGroupToList(data) + local name = widget.addListItem(GROUP_LIST_WIDGET) + widget.setText(fmt("%s.%s.button", GROUP_LIST_WIDGET, name), data.friendlyName) + log("Added group ^cyan;%s^reset; to list", data.friendlyName) + return name +end + +local function parseGroups() + for name, data in next, renderer.postProcessGroups() do + if not data.hidden then + if not data.friendlyName then data.friendlyName = name end + data.groupId = name + data.name = data.friendlyName + groups[data.groupId] = data + end + end + + for groupId, data in pairs(groups) do + sortedGroups[#sortedGroups + 1] = data + end + table.sort(sortedGroups, alphabeticalNameSortLesser) + for i = 1, #sortedGroups do + local data = sortedGroups[i] + data.index = i + local name = addGroupToList(data) + data.widget = name + widgetsToGroups[name] = data + end + if sortedGroups[1] then + local first = sortedGroups[1].widget + widget.setListSelected(GROUP_LIST_WIDGET, first) + selectGroup(first) + end +end + +local activeGroup + +local function addOptionGroup(data, i, added) + local y = (i - 1) * -14 + local bg = { + type = "image", + file = PATH .. "groupname.png", + position = {-12, y} + } + local name = "group_" .. i + widget.addChild(BINDS_WIDGET, bg, name) + added[#added + 1] = name + local label = { + type = "label", + value = data.name, + wrapWidth = 120, + fontSize = 8, + hAnchor = "mid", + vAnchor = "mid", + position = {120, 6} + } + widget.addChild(fmt("%s.%s", BINDS_WIDGET, name), label, "text") +end + +local function addOption(data, i, added) + local y = (i - 1) * -14 + local bg = { + type = "image", + file = PATH .. "optionname.png", + position = {-12, y} + } + local name = "label_" .. i + widget.addChild(OPTIONS_WIDGET, bg, name) + added[#added + 1] = name + local label = { + type = "label", + value = data.name, + wrapWidth = 120, + fontSize = 8, + hAnchor = "mid", + vAnchor = "mid", + position = {62, 6} + } + widget.addChild(fmt("%s.%s", OPTIONS_WIDGET, name), label, "text") + -- todo: finish this +end + +local function addEnabled(groupname, i, added) + local y = (i - 1) * -14 + local bg = { + type = "image", + file = PATH .. "optionname.png", + position = {-12, y} + } + local name = "label_" .. i + widget.addChild(OPTIONS_WIDGET, bg, name) + added[#added + 1] = name + local label = { + type = "label", + value = "Enabled", + wrapWidth = 120, + fontSize = 8, + hAnchor = "mid", + vAnchor = "mid", + position = {62, 6} + } + widget.addChild(fmt("%s.%s", OPTIONS_WIDGET, name), label, "text") + local checkbox = { + type = "button", + callback = "toggleGroupEnabled", + position = {165, y + 2}, + pressedOffset = {0, 0}, + base = "/interface/optionsmenu/checkboxnocheck.png", + hover = "/interface/optionsmenu/checkboxnocheckhover.png", + baseImageChecked = "/interface/optionsmenu/checkboxcheck.png", + hoverImageChecked = "/interface/optionsmenu/checkboxcheckhover.png", + checkable = true, + checked = renderer.postProcessGroupEnabled(groupname) + } + name = "check_"..groupname + added[#added + 1] = name + widget.addChild(OPTIONS_WIDGET, checkbox, name) +end + +function toggleGroupEnabled(checkbox, cdata) + renderer.setPostProcessGroupEnabled(activeGroup, widget.getChecked(fmt("%s.%s",OPTIONS_WIDGET,checkbox)), true) +end + +function selectGroup() + local selected = widget.getListSelected(GROUP_LIST_WIDGET) + local group = widgetsToGroups[selected] + local dataFromPrev = widget.getData(OPTIONS_WIDGET) + if dataFromPrev then + for i, v in pairs(dataFromPrev) do + widget.removeChild(OPTIONS_WIDGET, v) + end + end + widgetsToOptions = {} + + activeGroup = group.groupId + + local bannerOptions = widget.bindCanvas("banner") + bannerOptions:clear() + + local bannerName = tostring(group.bannerName or group.name or group.groupId) + bannerOptions:drawText(bannerName, {position = {127, 13}, horizontalAnchor = "mid", verticalAnchor = "mid"}, 16) + + local added = {} + local index = 0 + addEnabled(group.groupId,index,added) + + --[[ + local categories = group.categories or {} + if not categories.unsorted then + categories.unsorted = {name = "Unsorted"} + end + + local sortedCategories = {} + for categoryId, data in pairs(categories) do + data.name = tostring(data.name or categoryId) + data.sortedOptions = {} + sortedCategories[#sortedCategories + 1] = data + end + + table.sort(sortedCategories, alphabeticalNameSortLesser) + + for categoryId, data in pairs(categories) do + table.sort(data.sortedOptions, alphabeticalNameSortLesser) + end + + local onlyUnsorted = not sortedGroups[2] and sortedGroups[1] == categories.unsorted + + for iA = 1, #sortedCategories do + local category = sortedCategories[iA] + local optionsCount = #category.sortedOptions + if optionsCount > 0 then + if not onlyUnsorted then + index = index + 1 + addOptionCategory(category, index, added) + end + for iB = 1, optionsCount do + index = index + 1 + addOption(category.sortedOptions[iB], index, added) + end + end + end]] + + widget.setData(OPTIONS_WIDGET, added) +end + + +local function initCallbacks() + widget.registerMemberCallback(GROUP_LIST_WIDGET, "selectGroup", selectGroup) +end + +function init() + --log = chat and chat.addMessage or sb.logInfo + + widget.clearListItems(GROUP_LIST_WIDGET) + initCallbacks() + parseGroups() + + script.setUpdateDelta(1) +end From 1f5606b4d5f876774cb24a083361dd497c0d2cbb Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:41:05 -0800 Subject: [PATCH 109/181] Update StarClientApplication.cpp --- source/client/StarClientApplication.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/client/StarClientApplication.cpp b/source/client/StarClientApplication.cpp index 81b217f..09ebf0c 100644 --- a/source/client/StarClientApplication.cpp +++ b/source/client/StarClientApplication.cpp @@ -611,7 +611,7 @@ void ClientApplication::changeState(MainAppState newState) { }; m_mainMixer->setUniverseClient(m_universeClient); - m_titleScreen = make_shared(m_playerStorage, m_mainMixer->mixer()); + m_titleScreen = make_shared(m_playerStorage, m_mainMixer->mixer(), m_universeClient); if (auto renderer = Application::renderer()) m_titleScreen->renderInit(renderer); } From 93839a20323328e0acee060e78d77ee0b504774d Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:41:35 -0800 Subject: [PATCH 110/181] Update StarTitleScreen.hpp --- source/frontend/StarTitleScreen.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/frontend/StarTitleScreen.hpp b/source/frontend/StarTitleScreen.hpp index 65ebb57..9aaac96 100644 --- a/source/frontend/StarTitleScreen.hpp +++ b/source/frontend/StarTitleScreen.hpp @@ -4,6 +4,7 @@ #include "StarAmbient.hpp" #include "StarRegisteredPaneManager.hpp" #include "StarInterfaceCursor.hpp" +#include "StarUniverseClient.hpp" namespace Star { @@ -39,7 +40,7 @@ enum class TitleState { class TitleScreen { public: - TitleScreen(PlayerStoragePtr playerStorage, MixerPtr mixer); + TitleScreen(PlayerStoragePtr playerStorage, MixerPtr mixer, UniverseClientPtr client); void renderInit(RendererPtr renderer); @@ -80,7 +81,7 @@ private: void initCharSelectionMenu(); void initCharCreationMenu(); void initMultiPlayerMenu(); - void initOptionsMenu(); + void initOptionsMenu(UniverseClientPtr client); void initModsMenu(); void renderCursor(); From ea21eb55d765cd9479debd5831dbc593b88af50d Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:41:54 -0800 Subject: [PATCH 111/181] Update StarTitleScreen.cpp --- source/frontend/StarTitleScreen.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/frontend/StarTitleScreen.cpp b/source/frontend/StarTitleScreen.cpp index 895e88a..b48ac13 100644 --- a/source/frontend/StarTitleScreen.cpp +++ b/source/frontend/StarTitleScreen.cpp @@ -18,7 +18,7 @@ namespace Star { -TitleScreen::TitleScreen(PlayerStoragePtr playerStorage, MixerPtr mixer) +TitleScreen::TitleScreen(PlayerStoragePtr playerStorage, MixerPtr mixer, UniverseClientPtr client) : m_playerStorage(playerStorage), m_skipMultiPlayerConnection(false), m_mixer(mixer) { m_titleState = TitleState::Quit; @@ -43,7 +43,7 @@ TitleScreen::TitleScreen(PlayerStoragePtr playerStorage, MixerPtr mixer) initCharSelectionMenu(); initCharCreationMenu(); initMultiPlayerMenu(); - initOptionsMenu(); + initOptionsMenu(client); initModsMenu(); resetState(); @@ -345,8 +345,8 @@ void TitleScreen::initMultiPlayerMenu() { m_paneManager.registerPane("multiplayerMenu", PaneLayer::Hud, m_multiPlayerMenu); } -void TitleScreen::initOptionsMenu() { - auto optionsMenu = make_shared(&m_paneManager); +void TitleScreen::initOptionsMenu(UniverseClientPtr client) { + auto optionsMenu = make_shared(&m_paneManager,client); optionsMenu->setAnchor(PaneAnchor::Center); optionsMenu->lockPosition(); From 300b8f2dbae631fdddeafaee683f450418e5cc57 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:45:26 -0800 Subject: [PATCH 112/181] Update build.yml --- .github/workflows/build.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 925c2a3..8434c80 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,6 +3,14 @@ name: Build on: workflow_dispatch: + push: + branches: + - "*" + + pull_request: + branches: + - "*" + jobs: build_windows: name: Build OpenStarbound Windows x64 From 0a506401aa18cacb5c214823a1279a9a79bc5205 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 19 Dec 2024 20:03:51 +1100 Subject: [PATCH 113/181] Update StarUniverseClient.cpp --- source/game/StarUniverseClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/game/StarUniverseClient.cpp b/source/game/StarUniverseClient.cpp index b4edae4..70a227e 100644 --- a/source/game/StarUniverseClient.cpp +++ b/source/game/StarUniverseClient.cpp @@ -313,7 +313,7 @@ void UniverseClient::update(float dt) { {"mode", PlayerModeNames.getRight(m_mainPlayer->modeType())} }); m_mainPlayer->setPendingCinematic(Json(std::move(cinematic))); - if (!m_worldClient->respawnInWorld()) + if (!playerOnOwnShip() && !m_worldClient->respawnInWorld()) m_pendingWarp = WarpAlias::OwnShip; m_warpDelay.reset(); } From 6a1ea4aa30bd429037d430f9fd2eb89a0f7905bb Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 26 Dec 2024 20:11:45 +1100 Subject: [PATCH 114/181] change math constants to constexpr --- source/core/StarMathCommon.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/core/StarMathCommon.hpp b/source/core/StarMathCommon.hpp index 1627edb..3890403 100644 --- a/source/core/StarMathCommon.hpp +++ b/source/core/StarMathCommon.hpp @@ -10,11 +10,11 @@ namespace Star { STAR_EXCEPTION(MathException, StarException); namespace Constants { - double const pi = 3.14159265358979323846; - double const rad2deg = 57.2957795130823208768; - double const deg2rad = 1 / rad2deg; - double const sqrt2 = 1.41421356237309504880; - double const log2e = 1.44269504088896340736; + double constexpr pi = 3.14159265358979323846; + double constexpr rad2deg = 57.2957795130823208768; + double constexpr deg2rad = 1 / rad2deg; + double constexpr sqrt2 = 1.41421356237309504880; + double constexpr log2e = 1.44269504088896340736; } // Really common std namespace includes, and replacements for std libraries From 5de1e6cbc9129551c0292ae513a3962cb319e45c Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 26 Dec 2024 20:12:15 +1100 Subject: [PATCH 115/181] items can now override inventory filters --- source/game/StarPlayerInventory.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/source/game/StarPlayerInventory.cpp b/source/game/StarPlayerInventory.cpp index f64794d..0fed167 100644 --- a/source/game/StarPlayerInventory.cpp +++ b/source/game/StarPlayerInventory.cpp @@ -943,11 +943,24 @@ void PlayerInventory::cleanup() { } bool PlayerInventory::checkInventoryFilter(ItemPtr const& items, String const& filterName) { - auto config = Root::singleton().assets()->json("/player.config:inventoryFilters"); + Json filterConfig; + + auto itemFilters = items->instanceValue("inventoryFilters"); + if (itemFilters.isType(Json::Type::Object)) { + filterConfig = itemFilters.get(filterName); + if (!filterConfig.isType(Json::Type::Object)) + filterConfig = itemFilters.get("default"); + } + + if (!filterConfig.isType(Json::Type::Object)) { + auto config = Root::singleton().assets()->json("/player.config:inventoryFilters"); + filterConfig = config.get(filterName); + if (!filterConfig.isType(Json::Type::Object)) + filterConfig = config.get("default"); + } // filter by item type if an itemTypes filter is set auto itemDatabase = Root::singleton().itemDatabase(); - auto filterConfig = config.get(filterName); auto itemTypeName = ItemTypeNames.getRight(itemDatabase->itemType(items->name())); if (filterConfig.contains("typeWhitelist") && !filterConfig.getArray("typeWhitelist").contains(itemTypeName)) return false; From 3df5cb78da86912c30b6281f4eafeddd4ba56f32 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 26 Dec 2024 20:51:02 +1100 Subject: [PATCH 116/181] oxipng pass pointless but i like the smaller number yayyyy --- .../interface/actionbar/actionbarbottombg.png | Bin 739 -> 519 bytes .../interface/building/collisionblock.png | Bin 127 -> 117 bytes .../interface/building/collisionempty.png | Bin 110 -> 103 bytes .../interface/building/collisionplatform.png | Bin 101 -> 94 bytes .../opensb/interface/graphicsmenu/shine.png | Bin 740 -> 338 bytes .../opensb/interface/opensb/bindings/bind.png | Bin 306 -> 285 bytes .../interface/opensb/bindings/bindname.png | Bin 197 -> 152 bytes .../opensb/interface/opensb/bindings/body.png | Bin 743 -> 323 bytes .../opensb/bindings/categoryback.png | Bin 162 -> 154 bytes .../interface/opensb/bindings/footer.png | Bin 163 -> 138 bytes .../interface/opensb/bindings/garbage.png | Bin 96 -> 90 bytes .../interface/opensb/bindings/groupname.png | Bin 391 -> 335 bytes .../interface/opensb/bindings/header.png | Bin 411 -> 294 bytes .../interface/opensb/bindings/reset.png | Bin 110 -> 108 bytes .../opensb/interface/opensb/shaders/body.png | Bin 743 -> 323 bytes .../interface/opensb/shaders/categoryname.png | Bin 391 -> 335 bytes .../interface/opensb/shaders/footer.png | Bin 163 -> 138 bytes .../interface/opensb/shaders/groupback.png | Bin 162 -> 154 bytes .../interface/opensb/shaders/header.png | Bin 4346 -> 552 bytes .../interface/opensb/shaders/optionname.png | Bin 197 -> 152 bytes .../opensb/voicechat/activityback.png | Bin 163 -> 156 bytes .../opensb/voicechat/bigbuttonback.png | Bin 229 -> 211 bytes .../interface/opensb/voicechat/body.png | Bin 839 -> 676 bytes .../interface/opensb/voicechat/deviceback.png | Bin 207 -> 196 bytes .../interface/opensb/voicechat/footer.png | Bin 151 -> 131 bytes .../interface/opensb/voicechat/header.png | Bin 366 -> 283 bytes .../opensb/voicechat/indicator/back.png | Bin 383 -> 270 bytes .../opensb/voicechat/indicator/front.png | Bin 1043 -> 614 bytes .../voicechat/indicator/front_muted.png | Bin 1038 -> 616 bytes .../opensb/voicechat/pushtotalkback.png | Bin 187 -> 176 bytes .../interface/optionsmenu/body_blank.png | Bin 810 -> 388 bytes .../optionsmenu/duocontrolsbutton.png | Bin 140 -> 139 bytes .../optionsmenu/duocontrolsbuttonhover.png | Bin 141 -> 140 bytes assets/opensb/interface/optionsmenu/shine.png | Bin 774 -> 372 bytes .../optionsmenu/tricontrolsbutton.png | Bin 153 -> 131 bytes .../optionsmenu/tricontrolsbuttonhover.png | Bin 153 -> 131 bytes assets/opensb/interface/title/barstound.png | Bin 81040 -> 77149 bytes assets/opensb/interface/title/starbound.png | Bin 80794 -> 76785 bytes .../inspectiontool/inspectionmodeicon.png | Bin 185 -> 166 bytes assets/opensb/opensb/coconut.png | Bin 54869 -> 49258 bytes .../opensb/rendering/sprites/error_left.png | Bin 178 -> 164 bytes .../opensb/rendering/sprites/error_right.png | Bin 174 -> 168 bytes assets/opensb/sky/orbitals/orangestar.png | Bin 10592 -> 10407 bytes assets/opensb/sky/orbitals/redstar.png | Bin 10620 -> 10388 bytes assets/opensb/sky/orbitals/whitestar.png | Bin 10804 -> 10491 bytes assets/opensb/sky/orbitals/yellowstar.png | Bin 10778 -> 10513 bytes assets/opensb/tiles/shadows.png | Bin 166 -> 145 bytes 47 files changed, 0 insertions(+), 0 deletions(-) diff --git a/assets/opensb/interface/actionbar/actionbarbottombg.png b/assets/opensb/interface/actionbar/actionbarbottombg.png index 685ce2a68c8495127d02ee678aff8a2bf34643d7..2d3246d2b253ae99a51b4050367dfbe0ff480e7d 100644 GIT binary patch delta 504 zcmVw;Z z?O~$sF(O4#h78g^Zm)yn$JsU!2Y&(+kwXEO&om!D)$VNQ6;F^{xQW25_o65NMQDP4kmy1JA19itZ@d zD63i@wFAehAXczHnm)>^hP{dxs{nYvBK)di|6|x4#Tli9DG`XI+Wr{!M{!ikv|L-& zn?N69Iqy^zdVjA}bg4gzGD@Ze@#d%Vq6UuDs=Ay{;#_2`JIXo0D8W?W!sqjjRbWwF z$|A8h%E0_lB3aCN`wPgiN?(kY~fs$YDn1=2?P5haQ>*M5JT^70@Fc5^|(7x57i9_ u418z+A5!| zKJM;$lFi?z+$DPg2+*ccD@OV?mwq~YIO)R2D#LEIE(tLRIQVRt^s|$GI((=O;CC)? z8SRV!*g^W)Nk26{v~Zf^f`Dvi$#k@JN1|^w{R;7+eYmoe3j%_I6i!FmbtL*`(=Wt_ zWNtIM-^2s3QGb`9TfC{ge8&+G7o>17Y0;7Bn@zvFC%CF2ZKA0IwJvaf>XtIzTh0aJba z9o}m1=j-wJ`#G@NFI`!V7PE23(F;ZTRTmJj;|?Faa(^w#dg>7nAJlc5s>xv_FDPb% zj;D$BQKVmW0U!R#H{0%_#pk{ z0v5o>27ha25un1y^?G$hs48Z&j@bu5q+b;Qv+&VtmZ)mi4hf|nRzMaXuK6V@DQ1I? zX@-)16$Q+~hh%w3V&$^@eKG=s_;6+EnqQEKVz%s<#VF}lQNS#GNS23`H3alxe8goL zFXEJpLN*<;(m!LU(oc8{OeeeN3u;uX)5M-Bs zE~xlE90MQNGVkpgZLkA;V5<{k-~YReK!Xo#ErRU35#omI4|g&yMtuDFd;kCd07*qo IM6N<$f~Ra&{r~^~ diff --git a/assets/opensb/interface/building/collisionblock.png b/assets/opensb/interface/building/collisionblock.png index 5f78e28bca07e4d9f07a79123bcfd2975f5d6366..09bea46cc007aaea6ee7b5d03d5445a40d16f6a7 100644 GIT binary patch delta 97 zcmV-n0G|JUb&wfc1ONa4{Ct#b0000yNklSEGiTXd?~#=R-~*`%e7De4oSWp*`9)!4d3jhDf*d;8OK0etI$CNg-s L`njxgN@xNA`fewo diff --git a/assets/opensb/interface/building/collisionempty.png b/assets/opensb/interface/building/collisionempty.png index 6f8f66fb926c034e687dfb52ef63f919323f3d27..261ed749383d764d3295d3399e8992b0698de29a 100644 GIT binary patch delta 83 zcmc~xpCIYS!oa}rr)EkHkka#XaSW-rm8`)3$G)*AaOtawA2>r~`2u44S2{DQw8pkG mmC5o&lq#$_{ybq50|Q@!Vf&tM6J7&#GI+ZBxvXRMXp-WoEi9B2T8r>mdKI;Vst02k&WRsaA1 diff --git a/assets/opensb/interface/building/collisionplatform.png b/assets/opensb/interface/building/collisionplatform.png index 4744f82a652d7c342a0374ac183a9dab9f97d7ce..97a00f2e8c11e259d3554519aeea8792241f096c 100644 GIT binary patch delta 74 zcmYd|n;_}R!oa}rr)EkHkW%$@aSW-rmCVriKcj(>@t?hO^1+?i0s<#oCwjF_d?Az; cP?W*Mpx&wUI`xN_6Ho(#r>mdKI;Vst0I)R~p8x;= delta 81 zcmaz`ognGM#=yW3RvPmhNa=XGIEGZ*N=|5K`p?3^Y{no`@75!+>4{X%3`ThdEstZz kjx9gPBV8?WL4<+f%UQ3(YRi~9f%+IcUHx3vIVCg!02g!`oB#j- diff --git a/assets/opensb/interface/graphicsmenu/shine.png b/assets/opensb/interface/graphicsmenu/shine.png index fb130dd5b5d14c08db3edcf32d128b8cbd62f3ea..909cef39bc16f4a3763b8c11276bcc04ac217868 100644 GIT binary patch delta 323 zcmaFDdWmU*L_H%j0|P_EcV<~2#TMWb;tHhy|Np=A=KQ-r7E?)(UoeA6j;AC@{HLdj zV@SoVx92zJDjNzoT#VERSRoYBU_{uQw=QmbbBT}s?F^WC!cmzh;F>+da_TvDT+KXv=1=+n`cqYp>_ zHP3y!cJJ2h->%)e6q?)@sAZW_%kr|8DNNP$J#FH9_=@jYktIe; zGiNT#oUv==%%+fKCc2kRc!SMNgD0GtvMhDhvcy-*(zt?VUfSYw*~I7W6(2{f;91i$ zXSJ=IJxkLg)$6j6jW2G~UHdoBR4LTIH1Q+zFZP=O3!{JM{{w{CjJymA9IlQ| zH}-3#UC>Of%Ky!Jp?iXg=Oj#|WZb^?{CUPB2^0DGx)>T=8XA-w6a*C}a0qy?bT~4> z5JHecg^5LgF{yz8jvh^BQgUDrRA}H3aA4t3U^>FUh=dU0Ky6GN42BNK2&5h&&gjx0 zp@57K;tXKp**FvssDlBh9wH95wgYH16rs2U&8bN+H)6B%lOrRFW8oeIGoYTsrm^A2 z5>#{1{K%=$#3BF;O9e)k2@FaeJOU7e5MdBhY2XlYVCiIJ0wX04mfH$l|B}sIE!K8FXfL;m_kCxLZ*(7UcvdRTppc5=B$En zN@O~{xq!amRJc^AvQ9mKVdA$5J7zdAy4*Va$O@bU@8&ZFt}3^haO2-C1|aZs^>bP0 Hl+XkKLg%g` diff --git a/assets/opensb/interface/opensb/bindings/bind.png b/assets/opensb/interface/opensb/bindings/bind.png index fcf492ac816bcb6526d6c6fd09b71995e36c4c1e..8ae73709bd208134f8a2860a6236eb0387e74b70 100644 GIT binary patch delta 257 zcmdnQG?!_DO8pa07srr_TOkt|`;I8^Fu&b!{+<7?tEzTxy{n>?n;!c)ta|@@TFUNK zVY>5o^|-#SnBS!?#lQWJA?ICvpKqG4F0@;(`N&omFLk~{J!;af^7l)=zYDlm0wQQWs%Qf8K|9{<@YeOY^hL+x#5oho$~N@In%UY`)EYH!(osbb^h{_N7F zza0M`WZH0q<-vu_;{{1)d1r>-FpHnFMP>IB&Quk_lanldB#7Q#q`Lf)yPowd&zPHU z_0GyNI29x?d(UIw`nz`N($p7h7cv-nkqCjtvI`m391IVRmQN6Dx?0Qt1fH&bF6*2U FngAH&cd`Hg delta 279 zcmV+y0qFjn0-B!BryL_t(|+U=Gxt{gE8Lm%lm_Lg&tz3La4!rny?AgNP~Dq4OL z0am)+?>8XH_VSXwmh5HQUTaBS=V2ecytH&_*|OK4u3`PW)tQ<0Sfnj*0k78! z07_|FLEA!GiKYb#G+TwZ&PIQOX^LP^aOTpeDlKJy5PDqNB2lU~fMoP(N|HcE2tY`p z!W9-syDz|^$Wl3zDp-nQK09OqV5#T}v$b@b;J)vRr~X+_Kuv9__kBNi d(BJN$UsR!Nkq{+fdYu3O002ovPDHLkV1lGXf@}Z) diff --git a/assets/opensb/interface/opensb/bindings/bindname.png b/assets/opensb/interface/opensb/bindings/bindname.png index f7c45002b58b96fe8debb76af4a9e10e8d11992e..71de45f6d60384736465a6e23faac76cc691defd 100644 GIT binary patch delta 134 zcmX@gID>J5WIYQ51A}dV_B|jK@9E+gQgJIOt&qdGWs@7F7amTEg*lpZ*BdL9U7w4Jj+{c0rFmdZ_KqBrP4F5bi e)TXi9oUy_vZ-wfNDF=X7F?hQAxvXB zdTyt?M?3-ATC<&kT1CGA0000P@CLk2~w!44J8VA~geJtp1 kK;w75JjUC(M(zaXq-!=&@7eXOfqrH1boFyt=akR{06E!O^8f$< literal 743 zcmeAS@N?(olHy`uVBq!ia0y~yV4MJCpWt8vlE*~1KVo2DTIcEF7*cWT?R9IeW(SeB zKyK~jeDD0d%?r&9mvWn|Twl7%fum)HfMS2K*UVS$KaZ73v^};t-`6EV* zcb<8(Z4Pstb6VMBi+Q(BH%Glr63b({6wSC}xhW$96H`M2gMtDB2L}j|%{!!i`ph{l z1%(e=It-Zp94L?RirgM2!P>HY#a6wrhV}d&@A+98?s8IK1Ig}$cnant8t~K@92^(~ z1Q=LY7#JCWh^9QSC2$*P%!7FfVjltCH?9*VzI!bzrhaGtcV1H9sHTU#+rwU90%q`Z L^>bP0l+XkKH!ORL diff --git a/assets/opensb/interface/opensb/bindings/categoryback.png b/assets/opensb/interface/opensb/bindings/categoryback.png index ed838f3cdaa699d9e46ec9aacdf8b3c9c1cc372d..df244c4fcb613cbb1b232077976cf111e3a4c181 100644 GIT binary patch delta 125 zcmZ3)IE!(DN?D?(i(^Q|tv7yG8C?u{xFo-bRo8D%pL!*If#4I*gY4z~8yy`}epYqe zo|W-;%ADd%+li)6GcPJjH8#ILKYvS?-A!!{^u&5wcqlYI`&%%JYXBInkUrxl c@#B;fgDTU*3k8PkAq+s^>FVdQ&MBb@0F}cung9R* delta 133 zcmbQmxQKCrN?oR>i(^Q|t+!JRg&GuiSj>6eUulp0d2x=bLxN29EQ14uv(v0!r7oRf zv1Pey)J8i_v&HimPTYOEZr-|`ekYc;eJGFG$=K3iyMLeSnofZ>L2)y$bmizs4VkHL kwMByz!RTT9!#jT??H!*?vGkP)7i9nfPgg&ebxsLQ03Sy;KL7v# diff --git a/assets/opensb/interface/opensb/bindings/footer.png b/assets/opensb/interface/opensb/bindings/footer.png index 426f8a6352da4b45c41074454618864c15284320..6c6c4831cb8c08afa5d433a75f5eb3874d3ac589 100644 GIT binary patch delta 120 zcmZ3?*u^+OvXF&=fg#~zU@DLb^mK6yskrs_GOOSL2A%^4tY$4gwZ6k}al_r`rYf7P zJo{5!!#;Bua7eK5Fxkri2{y*&2FC*mANO(Gcw8)C(Bb+ZxxaE^sgMGDp)R+@`HRf; Xzat);x%-3{XgGtXtDnm{r-UW|B=9UE delta 146 zcmeBTT+BE@vYw5Bf#KATneTv9mZytjNX4zUR}XR?FyLWvEMGD&WZ!I$3+MSIlm0Um z8(crscVr^N8Un32)Jfk8lkfrW*Ekr9X>ygHEyvpN_GWcV2wA6O|U uF&zlCxz@qK$q;L??c)n4CWhSwd+dKm{+VF#G=qT~Xs@TMpUXO@geCwZ;WBmr diff --git a/assets/opensb/interface/opensb/bindings/garbage.png b/assets/opensb/interface/opensb/bindings/garbage.png index 3069741f04dbfb33f50dd555c0189520139b0582..2f3ffaaf97d4bdd9aeb88724c1220d308bd7c55a 100644 GIT binary patch delta 70 zcmYd@njq=O!oa}bHRIfDAf@Q(;uunKE4iWJe*(jE1%?QKz4XBvG)78&qol`;+0P<)RS^xk5 delta 76 zcmaz_m>}uS#=yYvU?Q6UkW%+_aSW-rm7L(f^nW4)vmR#*!@3EK+zx{6g#{N)f?O{6 eR@A!jFffQ8>Ms57-?j~?g~8L+&t;ucLK6T(Ll;#5 diff --git a/assets/opensb/interface/opensb/bindings/groupname.png b/assets/opensb/interface/opensb/bindings/groupname.png index 3019556043a9c3036ecc8f33573cfd6e6a496beb..c4d837ee389aad97e1c5c26c1036ea78bf538e14 100644 GIT binary patch delta 308 zcmV-40n7e}1J44GB!3o3L_t(|+H8{n3Is6-1E>D~2m4pO!$6SQf@BGk5(|62?<=lz z&ary%H?+dBhQ3!W7KiVf-0eNMa1SfN@M-1U*#pw(9OCg#gt@@I?cwZwAERGL!My>b zvES<24e65`ow(l=tKV>(s{Bv=2N)_J3VF?>SfEvtW?Gx8#eb#l1F_9eogk&kI9oWo z?{g3QB9?(f{a+r_avuiQHNf%&yh2bL1WKmbL@ z^k2@aCj>$Q$oqVNHP`|cFr33J;Xb{RRPSa$TV(tIFfd?XAn(2Z(GF1W<~iq$c7S>} z_udT$2I}2hYc2gnJ3zggbIv!~0qWfxV>BEX_`dr{>e&ZY%9p0pi492r0000TB!5mxL_t(|+U=E1ZiFxlg^iWl^&FgP&e7{2u|a|*9jObXxS0Go zfmw7J>3vcrO!DkFMo+lc>m}4M3`3stpz=)Doc49*vRB3NO-DIjlfPPf&~a0T?x>7w z9et>|)E8#vP!pwGu}021Hg(r`W4`AjQy<%$=^RS=A9_{Yjep|&q%$>9+f!=Z3s>({ z#GgaXas4r~zn+D{+NJS98{#AmUo;fgyxep?=A)$b63!vrlN?JqR!ZzczEsm05c8Yb zN%CF%L%uxB8s#<0cQ{iQO>?)TE4?zY)fughO#Qx`-}cn#=tIpmuEpukIF8>00O*SI zg@FO+5cRHG zmgS9B0MH-mT{q7&zQ6!`wwcN~XDD*)&Z_3j@EQcc`8JB*+J0000< KMNUMnLSTY;)3u}k diff --git a/assets/opensb/interface/opensb/bindings/header.png b/assets/opensb/interface/opensb/bindings/header.png index 287d2206592398141ad449023f303c18fd5290d5..ccc4785e3d1c5feb10e799583e2b39b2aa5c2062 100644 GIT binary patch delta 279 zcmV+y0qFjl1EvCy7=Ho-0002wjp9`R000b7OjJc;VqyRQ052~u|NsACuBiC{000AY zQchFq0O}sxn$7?K0LDo~K~#9!VhD9$pfO+!WeCw)MPsl+lp$yp%|R=J7ws)sNFPhI zXm80106TST)Bp?xL9{gbJq6nV>PH0R%Z!d;Y$e3X>(%UqoPO8Yi!LTeJ#i9i&wmdB!es%eEmG0NYcGs5 z0g1kr+Ptj+89i^0xdj9PVOl^+3u$R#Z2b>Bve1>DKjNEG_I3B3xAwOY3j~DQ1|)lG zCVSk~0jd4YY$!&}D9Oh diff --git a/assets/opensb/interface/opensb/bindings/reset.png b/assets/opensb/interface/opensb/bindings/reset.png index a75fd9c497e1656c18661801740d48a571a3cbb0..c91f11c0481fb824a1fdf82137d9c9ff7f15a4af 100644 GIT binary patch delta 77 zcmd1HnV{lf?CIhdQgJI;LGn*K(;lu1H=m!6|IxpUA^7rSb^ndpO*21;tYF|M&{le) hc1Y^KGUKFXHijc>T>nVS6FkWP1fH&bF6*2Ung9h?A3gv8 delta 79 zcmV-V0I>gTZjdBOHAzH4RCwBBU?3IzhXT9`(AnqDU-*wz0kYVWCr@!J0-5j>r~pMA luRCzL39rWgNPy&^0RY6TMf@R>@)!UB002ovPDHLkV1i#yA#?x$ diff --git a/assets/opensb/interface/opensb/shaders/body.png b/assets/opensb/interface/opensb/shaders/body.png index 272ed29cb23d057e6c369893881c006c880ec096..07d1cad7fa1aeba195476215bc476f4d732bf3ea 100644 GIT binary patch literal 323 zcmeAS@N?(olHy`uVBq!ia0y~yV4MJCpI~7Ik|x%xE&?h30G|-oq@*Mf5fLsfuK)l4 z*Voto3;mP^lwvLk@(X_T;wx+MyZb=y15X#nkcwMxFCOGP@CLk2~w!44J8VA~geJtp1 kK;w75JjUC(M(zaXq-!=&@7eXOfqrH1boFyt=akR{06E!O^8f$< literal 743 zcmeAS@N?(olHy`uVBq!ia0y~yV4MJCpWt8vlE*~1KVo2DTIcEF7*cWT?R9IeW(SeB zKyK~jeDD0d%?r&9mvWn|Twl7%fum)HfMS2K*UVS$KaZ73v^};t-`6EV* zcb<8(Z4Pstb6VMBi+Q(BH%Glr63b({6wSC}xhW$96H`M2gMtDB2L}j|%{!!i`ph{l z1%(e=It-Zp94L?RirgM2!P>HY#a6wrhV}d&@A+98?s8IK1Ig}$cnant8t~K@92^(~ z1Q=LY7#JCWh^9QSC2$*P%!7FfVjltCH?9*VzI!bzrhaGtcV1H9sHTU#+rwU90%q`Z L^>bP0l+XkKH!ORL diff --git a/assets/opensb/interface/opensb/shaders/categoryname.png b/assets/opensb/interface/opensb/shaders/categoryname.png index 3019556043a9c3036ecc8f33573cfd6e6a496beb..c4d837ee389aad97e1c5c26c1036ea78bf538e14 100644 GIT binary patch delta 308 zcmV-40n7e}1J44GB!3o3L_t(|+H8{n3Is6-1E>D~2m4pO!$6SQf@BGk5(|62?<=lz z&ary%H?+dBhQ3!W7KiVf-0eNMa1SfN@M-1U*#pw(9OCg#gt@@I?cwZwAERGL!My>b zvES<24e65`ow(l=tKV>(s{Bv=2N)_J3VF?>SfEvtW?Gx8#eb#l1F_9eogk&kI9oWo z?{g3QB9?(f{a+r_avuiQHNf%&yh2bL1WKmbL@ z^k2@aCj>$Q$oqVNHP`|cFr33J;Xb{RRPSa$TV(tIFfd?XAn(2Z(GF1W<~iq$c7S>} z_udT$2I}2hYc2gnJ3zggbIv!~0qWfxV>BEX_`dr{>e&ZY%9p0pi492r0000TB!5mxL_t(|+U=E1ZiFxlg^iWl^&FgP&e7{2u|a|*9jObXxS0Go zfmw7J>3vcrO!DkFMo+lc>m}4M3`3stpz=)Doc49*vRB3NO-DIjlfPPf&~a0T?x>7w z9et>|)E8#vP!pwGu}021Hg(r`W4`AjQy<%$=^RS=A9_{Yjep|&q%$>9+f!=Z3s>({ z#GgaXas4r~zn+D{+NJS98{#AmUo;fgyxep?=A)$b63!vrlN?JqR!ZzczEsm05c8Yb zN%CF%L%uxB8s#<0cQ{iQO>?)TE4?zY)fughO#Qx`-}cn#=tIpmuEpukIF8>00O*SI zg@FO+5cRHG zmgS9B0MH-mT{q7&zQ6!`wwcN~XDD*)&Z_3j@EQcc`8JB*+J0000< KMNUMnLSTY;)3u}k diff --git a/assets/opensb/interface/opensb/shaders/footer.png b/assets/opensb/interface/opensb/shaders/footer.png index 426f8a6352da4b45c41074454618864c15284320..6c6c4831cb8c08afa5d433a75f5eb3874d3ac589 100644 GIT binary patch delta 120 zcmZ3?*u^+OvXF&=fg#~zU@DLb^mK6yskrs_GOOSL2A%^4tY$4gwZ6k}al_r`rYf7P zJo{5!!#;Bua7eK5Fxkri2{y*&2FC*mANO(Gcw8)C(Bb+ZxxaE^sgMGDp)R+@`HRf; Xzat);x%-3{XgGtXtDnm{r-UW|B=9UE delta 146 zcmeBTT+BE@vYw5Bf#KATneTv9mZytjNX4zUR}XR?FyLWvEMGD&WZ!I$3+MSIlm0Um z8(crscVr^N8Un32)Jfk8lkfrW*Ekr9X>ygHEyvpN_GWcV2wA6O|U uF&zlCxz@qK$q;L??c)n4CWhSwd+dKm{+VF#G=qT~Xs@TMpUXO@geCwZ;WBmr diff --git a/assets/opensb/interface/opensb/shaders/groupback.png b/assets/opensb/interface/opensb/shaders/groupback.png index ed838f3cdaa699d9e46ec9aacdf8b3c9c1cc372d..df244c4fcb613cbb1b232077976cf111e3a4c181 100644 GIT binary patch delta 125 zcmZ3)IE!(DN?D?(i(^Q|tv7yG8C?u{xFo-bRo8D%pL!*If#4I*gY4z~8yy`}epYqe zo|W-;%ADd%+li)6GcPJjH8#ILKYvS?-A!!{^u&5wcqlYI`&%%JYXBInkUrxl c@#B;fgDTU*3k8PkAq+s^>FVdQ&MBb@0F}cung9R* delta 133 zcmbQmxQKCrN?oR>i(^Q|t+!JRg&GuiSj>6eUulp0d2x=bLxN29EQ14uv(v0!r7oRf zv1Pey)J8i_v&HimPTYOEZr-|`ekYc;eJGFG$=K3iyMLeSnofZ>L2)y$bmizs4VkHL kwMByz!RTT9!#jT??H!*?vGkP)7i9nfPgg&ebxsLQ03Sy;KL7v# diff --git a/assets/opensb/interface/opensb/shaders/header.png b/assets/opensb/interface/opensb/shaders/header.png index d4425f0f29f705b147684742b4781c38535f5e62..d8042acc717f8270417a89049c48823bab028bf7 100644 GIT binary patch delta 539 zcmV+$0_6SrA*ck97=Ho-0002wjp9`R00CraLqkw$V`BgSc-obbGoV*-6o9|0Y`fc$;d} zMWYhhEIk(PHFD%oek)HeA_1IhBWm$~Qr$3PI!FaTPdyxsgMTy==$eX$1+N0?>CP+z zqmgdJ$c00uFPkrXhS1TKE!w814v0Wn51fZo5!ZzA#;NrKtPE<`Lnf|S_DC6y9=C!2r_Lm9A|2h;Pc7Pwa4Ml(fZ;w zav>Wr;75?yhe7Xe(~hE=>sK=DjkbMa)|qGYow=>+yzLua` z|9CmKPnY*~3cD`xi@}|XmSjEjd+eQ7@-&HMB|Mzl>~6lh^Tz8NF3h7>Nxrh~8y%$| z^&RSsYKE3R9avd>96A43x-tF5mxmqAZ!e|%e`YTF;)&NqJ8}qd%@8=vyQDRYIfz!xrBbUc`wuJa%EM`+vHt*R{K2Dw)R@0Cv$7Y zukyS8`pGBVzW2M1m6ax!=B8dps%ynUc}v=NJ2T4Ph>0J!Mz1W44j_9=xLxn>oMAX; zdimnEHsZjhZ(nFaH>JL=d9#PUurz!6KZj~sk#z%Uwv*p|{1oTK%TqK>Z@B$!rlF*v zp8Y|w@7FDdHXTTND*fIzIrp>tgUc2ksn&HYAM9y+^5m)X?xthX+-3Hjoc(z=PgbdM z&)1I}?#}7QPnAF4#aua0Jf3lRJ2-eI%az%@rg6qC+RW$nCEYf&yrytDFRb|D^F`I) zroEOSm2{mr)W8@{99(pL?uKa9_WieaK2xC8bXrbz&wuyGtXFoo{CE9VmP_gAaLU?? zzk9GVv1h~9zOU{dT5@0IZLhxipZnihD84p5WyOM*vO5Yl@Au|R8>slklZe*ON;y#1 zS@XZ@YsmTM{?apB6g7|U%zofp|G7{5`fk|ITpUQA-y$_?PJK`URTmSWy4HABGF&*Q zWBITT=wd+;$__znD`FzcRRJ0GfeImH#|Ao%V5q>`u~MUl^oR~nDHPO8ps0RTF;`#3 zS$S;59a>wAfdD}uvuG?B2t}Bf9aC``I9ALAhN>=dl^t8-@uH5f1W<#{pd)ctOsJ)? zJG7`x;{8maGj9|EzS*%#Sr!?Bh(@Ejs9qPADhSGIwGt#v&@>J`@JL-qW@C6LvP6Lx z!Ek~ICkdh~ghQx;$@;=IvK_t=M-ssx5g!qeU9}Ko zG@&1ih!n#^N)&=fxJKfDs}_XhCGikEHy$t6NCCARo+Cg21fgpLu1ZZ zMjcWdsppJ-8V44O88;YdKW+uA4+lOyYotgM&H1=ED0e6#vmp*BP!L=vKpZQ_lB~sQ zhJh9uHvnM7Sv||*W&r%Gk)%y}pFa-bUP*weWCQV8DNsCw;vo)c&|7fc%$sn79;(Bl zXDOVtS`9`MPtiUKs8Bq|WL-DIvnv0$$A%VvS63 zm29X2!0s_B*D<^B15%(_pU+5{Ot{GmRbU{29%p?}6h^CFPg+d89&nb4=#j8rjl6sVe?d`rS=yV>-wrQYNxpmXo$8efx$5Y65RPVw1!WNgnU$`5ry;xA=R;$%?Dn{l z|CN%Ss3Fd-EqVl+o^?BOi(?;N`k-rO0+sscdkcDRePxTh?VIf_34e0z9^8k0*|>H0 zU|)4h9Oez+nd@C zCp63x)*~;zbl37!WQRtBBqTI6ASjB!;ZJ!RZ2enPleNEh88Tc_b*VP_-v!u5Eomu~ PQli_n%6agv`x^fb1g{X# diff --git a/assets/opensb/interface/opensb/shaders/optionname.png b/assets/opensb/interface/opensb/shaders/optionname.png index f7c45002b58b96fe8debb76af4a9e10e8d11992e..71de45f6d60384736465a6e23faac76cc691defd 100644 GIT binary patch delta 134 zcmX@gID>J5WIYQ51A}dV_B|jK@9E+gQgJIOt&qdGWs@7F7amTEg*lpZ*BdL9U7w4Jj+{c0rFmdZ_KqBrP4F5bi e)TXi9oUy_vZ-wfNDF=X7F?hQAxvXB zdTyt?M?3-ATC<&kT1CGA0000^Be*8?kWa$%i<4258}zN}NDBQ-tI8^u52e{F2Ullg!-Y zdrVpl?AJ|r4|?h)Xx~U$QKT>iCr`M2D)lBFZNBlY>ihpr=6_~t z3ucP7Y)svLFs&uGUw#YNt;#Ez0XaX hqiZQ$U^&iO8pv77srr_TW@Ec7CfxL;}XtOs@D4SiJNar3kzq-gR3)K=d(VW8*BfF z(XmrR;N&*lzg&gW#y8Acvi zo^kn#|5L`4-H%RvFVCE}t~d6X!se?Nr@j9Fx1nciTJ7|V)OfysPR+W@i@rtd(UOxq tqGqEtcc=inp<{R1He~;W}jz7(NF7c;&NEibUc)I$ztaD0e0sth?VkrOs diff --git a/assets/opensb/interface/opensb/voicechat/body.png b/assets/opensb/interface/opensb/voicechat/body.png index c76bbb42239453846f8ae506db99e948c929028c..0eb134cda552e9f6ebb11a25cb61c849e3c6eddf 100644 GIT binary patch literal 676 zcmeAS@N?(olHy`uVBq!ia0vp^zkv7z2Q!fT*1)q8NSzPx32_C|XU?4A;^O-M|9?_a zl8A^%eSLjGLPC6ed|X^yY;0^yOiXlibW~JSWMpJSL_~Oacvx6iXlQ6iNJwySa8OWC zU|?WCK!Cr$zn`CCcfhljhnyPKPvtE;Pvi;J_fvy+pPqobpP zgM+=jy`7z%t*xz%jg7UnwUw2XrKP2Xg@w7fxtW=nsi~=niHWhXv5}FHp`oFHfq}lh zzMh_*uCA_*j*hmrww9KbrlzKbhK9Pjx|*7rs;a7rii)zb@=CSbFrb%QOM?7@|NsB` z|J95CzbFE0Oh0U8U|_WOba4!+xb^l9^DJja0k#7d|LX6#cO$L*?_W(nR{q6Sb^E-I zed+4M3hL%Bm_Fy{^5%LHoz!%2}N)sglw96-tKt z=AM6EZ$A5MZJ>y`gO2azJ33+0o&i*e*5iQYODF?n{N!C$kbZR-L>mO&i31~`%Br^ zCG?>i*un>~325LK`5%8S+bBf5cwe8wzojK^+S8Q%c`>&uUTsZ&T)ypXu}s$eWXp4U z$$=vKjlS(YzftCS!29K|&Dt-#-c|Q$C;P^bP*cv**Li0xGUlI)GUj92lqM6SxUd=F z8;GM3UbJsFeXLON;#yBL-@@l})?Q$`=f3%^Z@q1^S7h6|@R%`x%){HvT)zrAa$ zxnTG8;{;cZ6V74}xj6B}&o9e0`fLZCx9^iE;jn$4(<;^>_bY2_ky(ODT$Qh8ZKe3` z|4jBR`{LIBx2QFkbwPez5y)2<@r@KcSbPRfE{O01CmB#6Ljs!kbOcg~9Aenbg(bxU ktu6av^yKI8b-c7!_;l;sP2sp{zzo9R>FVdQ&MBb@0HkD1Z~y=R diff --git a/assets/opensb/interface/opensb/voicechat/deviceback.png b/assets/opensb/interface/opensb/voicechat/deviceback.png index 8f25473fc6b03bf385e420e338508545238ee8b1..0d0509ff28fa2a5bf9ccd40b7a3544b4d40d9d80 100644 GIT binary patch delta 168 zcmX@lc!Y6+N`1Gdi(^Q|t(f~^Uhw+`};kPMH*&&zImZM z@x$FltKA;v3pY2vXL@&a!vAltBN%{yaYp7piOMSiWqKY#x#F%G0}yz+`njxgN@xNAT)|Ns diff --git a/assets/opensb/interface/opensb/voicechat/footer.png b/assets/opensb/interface/opensb/voicechat/footer.png index 98fa09b48893ed1eb0cb692e7d21615af1321104..244d10622512a9c0c731e8f7fce2f0f8871a24db 100644 GIT binary patch delta 113 zcmbQv*vvRVGK+?N0v?iZ?QWciS0ekkO; z)YPg~>4jG=ER^20aDSGwc?l4`5Ix>!BP?4bW&NpH_RszI);~Gl|F84PKbywakZRhZ Q4m6d))78&qol`;+0EhxD2mk;8 delta 133 zcmV;00DAv}0ha-g8GZ%;007Oi(w6`L0A5K%K~#9!?bAUGz%UF1!7wr>!!LKus$f&=pjPjcYjWG6Z>x#%PZ z{y=u314IWv^tre`BHJE4p1n@=_n-RGI=5<$(c{&zsnm$*M1S9Hk4&)YIY%e)k=(L< z=uwC0*hKq4bfT9;-<$B2yHO^esN|8hXg)3OxY4%i7=Y+qL~ph9&*t+>eQ0&P=pFw^ zZHTTIKP`G@SvtDt)fEWwiB9xjA9^m`v-!N{lG%(imxmPD}`2dsQh_Zx)Z(m^ZINb%$y;5j}K-@ xPILf72Z#=U=m3Zgfan0eDEd_hF>Tx(zX6O_&)D!{UvK~b002ovPDHLkV1oTot`GnK diff --git a/assets/opensb/interface/opensb/voicechat/indicator/back.png b/assets/opensb/interface/opensb/voicechat/indicator/back.png index 44b81473fbca892cbc0c934c923d0013a2764459..0e31e86376c931b674ccf8abd849ccbdc84aeaea 100644 GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!4Op0gWTZiq5Rg&~@Ck7R(zbYk#41BUpdzl4 zAirP+M%Iw1$*b-^{P|pT*I}UOBu^K|kcwMxZ*JsmEEIA5_&CyG@&D;wOF2cX*4`4D z!js6TRC)PkLknk#`pli#;{an^LB{Ts5oL*&Q delta 368 zcmeBU`p+~$qMn0|fq`MQoVy|e1EZU#i(^Q|t+#g#yAB(OxCZXLuxSr>=&fnx3w>wm z9KPDaqviUD^WabB=Lc6#dL=HN#N&DL3=rhq*|l!x>e$!c-o2<}uzMnro4MHZ=iP{@ z?;b8V(0lILl>IGPFU{JS_r1uuP^21>#M;tvZR-3+K312&dA9Wl-_LM$eDl#h-xMm# z&avWL(^VNZjumH{wp#NDT(IMwHr=Ulg8uY#O-~IRJepWJ#2OM9n^Yr!B!`$nL?07G zfK?%a0V)X+2C@|(N_J=ff@YRR%{}I2ue^ovoGs~5851zVv zxUj+DoZ3^9=>H2W1Oz-h&tKcW!BR-zz_hrv^_haY4{mR?ik`AA?~lzFAMPE$XNG#d z&#~!P|9EQq-P21CERW}s1$o+XCJ@~0{mmMnHHn*hIuBolZ%*>pgTdc0BEvur9Q7kcwMxF0?MZ z%^m0+} z>->u+iOBb{&sAGzblJ0A`QDQD=gm2^a$VH0?H zWKYA*fG0MZOicxIW*p2pWzn0+5YH?r>Ex?>1`(S!?JHN7UGrYE?M5j_m!jj-69JZ+&WN=b%{D!$ za7CqFwBT&OfxlsI&Gz1^eU@=xaij5bjd_bJUWmw93HrZi65hrB;c2?Y2UVGSpmgHt L>gTe~DWM4fBh~gQ delta 1033 zcmV+k1or#p1d|Am8Gi-<0065VM`A4q?CwL#4X|&ag8`f#kEiuZDeAzk}n+h z2PVFru&9KPy+xcO?ony2)Jd6@)vD2GnA5ZK@JHr0u}#mW836#4gg8ar602*Rcf>*B zB9+!Ct!L%7fq#Ll7B*v+6ae-pu(7(wxhU8kKImyp{WdU=)sW=_fCETt=%p2G52yZp zIgOY|vn%LXQCR`Np(`!tByGee>MA$;;5ziaXT@>>KnbZeYuuR#aid zEENFMKv>dt41Rd<)$1Vf>v zjV`=;{l@qpEdVGetfn6>jqWewxf_Z1^AAchuRE(i+%3QEg+$)|i_g|d?0EGn#{ zw_Ov4!v=t`DiPMYtcnV2T~5x6VI6Es_?Vy&768IR zSO9>qik>AzSO7qU1po*OVFAE@DJ;$s0>G0M7JqYC08r~KA(QR^P>Ha(mJk4HFRXQG zakmBlsI{;*NsIeo0YL49wF&Mx3II<=SXt8Ip6&opOJSu+i>KxQKv}}7N#Z7Pl)B0>6@wl3 z|6N|Quo<#!0B`_V4b?%;Nm^Y^!_RbV7V^gF*?A}}DlGumcV*>dB`#7~E!0sD7}=~E zjYcRfqx;BMJN8YM6aY#TR8!p&`<|7Tm4CQMoTP3_WuhN&rC89@B7~62BhCr7fh%>= zMn-;nD9tYE(93B>nS}_3O9>%l=ZI6pE#eq)jW*c*HgJ@;QtN1wD~aw$;t3(7>Llu( z&Nf?2IgKc@4>GVNQ>IH6ln_#4mg<(7x~98HNPhuqTUR`Y9i|`v0000IuBolZ%*>pgTdc0B?dte;^4TN% zftHDt1o;Is{Qv*w>8=Wezsu!6NBt{K`fSUjl79a8lhhWVgZn*Q978H@y}8i3@HT@8 zvx8@vN7Azo|BScIKe^?=Zb3eIru)URXC;n*{lj2?G*Dx+R!>rmr!a5rb+b8!zPGO^Q$Qz*Ql@wWF}2J zoO8n1ud6{p#%*4L*<1_0M22|V>>0AA)jvO6+1PY5aN}h5a9!^+ws8k)v~HeiUEIc+ z_U`-de%;^=6PY_>_Eg!`r$`3PO0SLiSpU0hLbCx6b6|*_r(o{8de;L%b}XSc?k=+5 zy`jeG!m;FyUOH=%_whEnVX0S)@KIgt3H0 zs~zxKo4GZibE|GdM(vKdZaQ0}!jj%%OpDRk5h3pJzXrpRRYFzqzLA zf40tj-o2$C>`u=PdjDYVyN;t1w$78bN=dDW_g^A=KbU9bZay*RH8Q3~+V0bCz6wa& ztQOfmYYFQeE0Kb=W&h7bz1_FTOe=~+#@#x+;Fgnzkq#;R3Pe@sCs N#naW#Wt~$(69950_k92W delta 1027 zcmV+e1pNEx1da%h8Gi-<0065VM7me<@g01LJVl?t9$lyNO}rY_25Y_pI7$GyIZ zZ^le2A!Kh6=ZJe$S_^g3%9Yik(P)^n^Na9H?rmb5u1zxn04ND@in=9M*EsKpgTzHD ztzlNp%54J!S%1xJMocLH>``DNb&qpVusvL=X-)h#Fp$-N=>vcYq&4u;3buz6|Gr#C zOr+Qq)T~%p0YKF&E$1XH#3$-1*Zbfq^uA`rbOAsOq~&T_;wD{XiK|@0mbAgqmLB}t2?h=4X30{{qXi5D+lnXD9%)!)-om*)hu$ru1Y zScPO23V$no_jOu4&j~0?R_QVPjQ|KMS6HE(K6Lw;$$DJGD*0qdD^FGk3jkrQEv!|t zdQMnHq_vLR003c?F06H>g{%OeQemar8dgaOSph&TgjGaZ$O-^zBP{81FDfl$1pt)` ztBACa6#%fp0sw?X4GRGND`9b!5C9HBSoC25z<)sqi%xd{s7zSgO9%k97gkzYJgor$ zYAvihY4JQP0H~d?^5BW10B|tES|u%>=?(z36jqkBI5h_V$`aO24pQY@LIBuOR+$H> z?(C>~PJRY}ErgYMRQ*(5TwYy!VZ~+sXecUV1psRZD;6h-n^aihs_0H$^!g`WSocg7 z0Dsg#Soh*2agz#5TorX}l2)r_;+wIT)`;l>fC^LBMNU0qGW&$Ml3^2XWuMJO#+S^%)`m6el~xJYF+Q%5Z^v{^J7jZj)f z_mQzy?3+v}0F)@Grn)8eH7hSGagjJl-F%eESU=#FVnI!d5JGkyaZa!eT&RqU`;M*;*euK z7I-u_eZixZ=X%a?1lhh?cWTEg!7-S>Z&-A|vJd+_g* zk|*WK|JVMkWvgqG%384yN>ufqo5tsnEX}}TdGULAm<#Vs1|aZs^>bP0l+XkK`lCiD delta 159 zcmV;Q0AT;H0lNW^B!7ZQL_t(|+U=G>7Q`S3Lj!uwzTT^wxu`G%S#&PYE(WX;5`BN$ zd8ugBP=U(eAUbHtc4LD^S|fH|R|U(m+|8C#m@k8^5GzNc;Z%`hyD?0B_}U#FCp*vT z<^9Gx=M1S8Dx0vQWPX+3W8j#0p&HuIhBmaJ4Q*&c8~WeS^BDP`?JxN3gkW?g7!Lpd N002ovPDHLkV1nbRN!b7Z diff --git a/assets/opensb/interface/optionsmenu/body_blank.png b/assets/opensb/interface/optionsmenu/body_blank.png index d7703419a98b924638171c97fa04c97fbd2727c1..4127905d555ebaf53c1e6318d2330d2af24bc720 100644 GIT binary patch delta 373 zcmZ3**1|kNqMn7Bfq@}jYtLCA#aJBV?!>U}oXkrghqJ&VvY3H^?=T269?xHq0u+=E z@Ck7R(s01e&d$lnX>M+AVqyXm6l^fN0;D)fg8YIR1WjD0y!i0JHD$9fQ0$$ji(^Q| zt)zzL9==)4X35FQjBFtc^%?i$d<5DSYBcDHn_sxZD&ttdz%6;3A@ae}h3gxOIqMHU z6u#d(ZQb#tjW@n)&-mN%?uOdt2pzHRqe&a{`jQVOZLIrv_I#PT*zW5Gx9mNC=`+XX zQWN*&Z2uW|Ul(kM$hq|0EZfVMS8R3u*%Y0y`>UAN?7O->0!;XuY>dds`(?bZ>KC&# z*uaQ4HP_AxcKasQFP+kGt$a@UZLUqZi5of9Z|;bgdbCR3<9?RHnti4+*(TFB{cT9u z0F-+@|H-_m%db4Y269rJ{*Dbm*ZucS+!*mjUh0R(s;h($ literal 810 zcmeAS@N?(olHy`uVBq!ia0vp^Z-96g2OE%F%d+qv0|V1XPZ!6Kid%2*I{F=QkZ8Eb z=5cCGOqGbA|Tf=b(2!8!yS*FWhQK0bL*e&?d2BsP5WWBwB*IAnJ3aV z|9r9Q-9pB??Hk|kdRO@%{JrnxJ+*)TOrH9%#e#*qi4}r5#8|kmi061^rh7auw~&!L z>mGJ3EMmhUCS(O1VgfoKtPlah4jVw&f$iYD{j*wZX7uO0S-T;j6=)vFEF`6GLTz+; z*($4KBN7=8GBxd;`8NGyZ>+iHT)*|ffBKImeN>6qXmru0&-M2Azu%_qzrXEmw`ka! zKgnDCIzj4LK^W*rUhSn@K40{U{Hz&qG00)f&bvPpBHYvTPQ0Avbg=3BhK2;jgG~wA zkF*MFz8&tGn(#Tpeocg?M%3~n5E+P3ZK>I@l~5DD9kwzOZutw<$$0SGq0mP^-n5Hq zAAEMPE@ER)0J;NCU)%NRS@4EMOB*8IwwI=;ar_2*i1lD!p&&ckTMXZ?P>3+UTz}st z=y!xfyFAgsS+%WiqXA#DO*H!&xZ9YT);izbra!&z`uD%rIIbGYH}NLDXf^nDXyKWk z0y-9|Y~WZty(A{V2q<;P-TayJh6ht5AWYRqeCl4TYMLWV?4lYoZ^1dT{N?n;oWt zd)hJMSSO%l!|}%#Gnzy(l8A!C2D$th;-4q-_RnU~h8TV$TX(wmV$LvV8fr*zg!;7c c_Yam^Ki{1a%APO_m}H&xk{;yg;uunK>+SVc-i81kw!~8gbJ^4NQ)2JfcJ0kB;;z~FFRcEl+N*?1 zCd)&a175NjuD$hO#j1~u%zPFP8i2(A0~=e_KYZf6!*wYsey?F=MMc<-pZ}{j9a4*8 O00K`}KbLh*2~7Ze3^4Wp delta 111 zcmV-#0FeKS0gM5VBxqAfL_t(|+U?h|2>>7r06}$_>>~&c7MxcLvCtHjihkf1I8r3e z^{Hg)Fsg-?22hPD(~`jvk?#Ws9B{w^2OMzTzzLosaC-!@F}CTyx-ozF@oc#H|9i~9 R-{SxP002ovPDHLkV1n{cFeCr~ diff --git a/assets/opensb/interface/optionsmenu/duocontrolsbuttonhover.png b/assets/opensb/interface/optionsmenu/duocontrolsbuttonhover.png index b43f7320bbdefcb98ee2115f102ac7733d622c6a..6709e7149ba51005b732ba353f334f9a6963eb21 100644 GIT binary patch delta 111 zcmV-#0FeKU0gM5VBxqAfL_t(|+U?f?27qu3h4I!6BRbf0prLauRM_4DO8;+s7x;m_ z>AocCf{8d<^Z=#%-Xg(S)@}H}0S6p#zySxGf8fkkaWtMl6{NbazL>o{JWrXJ;jI_C RaNGa@002ovPDHLkV1hX1GW7re delta 112 zcmV-$0FVES0gVBWBxzJhL_t(|+U?gd4ge4gKvCRKB5^QrAcJ!;h(S9T3BSp|z)OeL zm@$o11E!Qpq6ySe$|O=aKE&?>2OMy~0S6p#-oSB|BXD~JvN5{lzq&Dd`0?zSnBlDx Stkcf`0000N~q-Hu%F4%+1a^k*KXaq?b@|lQPJ7l zA-+ea_;!jcOMJB~ZPl`*Q_EbqE*q2v8;1rPrUomuX3p5Pa^|X)Gd5{XJY?c?_lnQe z5TBb!N%a}>gTe~DWM4f`G=y3 literal 774 zcmeAS@N?(olHy`uVBq!ia0vp^CxQ482OE%lvi9)@1_q|Ho-U3d6}R4AZscVU;Bh_3 zm-s(4n^kbhj_H3`uef?Nr>6Z*)YElH5L8&eA>hHnp~1u=#K_di(CE@2p@LvLC^;wy zDog+?QDHiwz<30Si=+dn35z~9P6a69P+;p|V039cvlW+_9t?siY#cDup}^=efk6o**uWv=z{07}bcCVt2oje? zz>x{2ibueM2Z@WKiW8z6Svg4FBVMsE6JY{E%ca#GF+pfnvk1J*Qdy^p>>3tvdsTmQ428vku}XR)tHBDsjPJD<)1;{@B#SB9O_~6)p^PRB^zb iDG7`&lToXI#rqMn7Bfq|iQ>ZV&jN;JSH#1%-Zsi_5qgaa9qCr@PrQcR2!wwyTwWH6Ql z`2{mLJiCzw PGMvHF)z4*}Q$iB}QXDK{ delta 137 zcmZo>oXI#rqMn7Bfq|iQ>ZV&jN;JSH#1%*fhJ;U^JQc_|cztSpngFahDhmJr diff --git a/assets/opensb/interface/title/barstound.png b/assets/opensb/interface/title/barstound.png index 6c17d8d435f96478e9343d2ad599e896fa9864c6..d6e14af443aadd196a0320082391c95ae8c60577 100644 GIT binary patch literal 77149 zcmaHSWmuG5*EWiPfQWR1w6s!#bW0W!Es%I)16$OIe)`SB5T`6E++$5D<0jUD{UW|*51d;j?wmWErfTv7G zd{CGGjXAt4@hDWTqc|#{&X~~%laro0YdXN9hzt!3M*lTftZNfmOn`ZFhlTU3;?qO( zb>UgM7$)aQrWp9u8bP(SYI`wpuv&Yp#7tg9gkzde>E&DYB>O5^f!73%Lsb*5DJ9Rc zk86#wl<9RPJA6k za=yd4e28Q`NN1H=tCL~n?AUQ71kER`c>_{Y^Ld2hz%}gUUmJHU3P`wjgC{JJ0pGa# zPMA_gol2bXh8v;?Ir~dUO+aU8B4N!tfRZ0uZkjDy1pg!D(}~!P6yGz2wVK4Axcz4ma6iexxh1_m zKB63j@mKDno7o}{;_wI=Nn_d9D(~#oJOoyK=9YBdXu5t=kQ)lKMtgB&**E%>mDRwn7{lk{NaAHL%z!Y#=F^9XKfBwNyh+lf>i)y}gQL_JeDl(pJ;fr7 z)i<=F@C$)ub$ZVzU>d2KiA606`PuJUD-9RhwGcA<8bcla`D6x@@C9;_c--KPf#8yi zFm>b)D@8DtO#T~EEx%fgYA%hYm0coFk_paD(IggLaY@|2YFc$4&%ARFXZhU~UJDI$C(Rs zityo`GGLSNW+7bVAFQ&|HZ$NtgKc*%cOsh{@m?Zy&yjt#eDCMo@Io-`Pm2PSlFDz+YB3AZZj{b_1 zl#oBd)&h0;($y;d$W#K^mt+F3q>hLeBOHV*_- zZ;v!s0o(kBFp&u?xf9--rcn$na5ZP$@mszzpu6>mx*UxwoUtZ z@n?gq5@?h|Ia5N|rH)G@c1Gh~Oxo(o*TCAnE-K{NXRAwjR}ou-8{t$ z-Iw>$oeHRiok?Gtsh9CP0;+{6HVKghT+mcX$4Q!2kV?vrlciXnd(FWk>{m*K<8(-S zO-@J?61UBIk}$V?EX9)mSs#Ev`H=ZbHakc=@2fLdtIwyawSRCzaF%f zAmui-WPjSf<+J)G(t|!2H(-Jrz*)xL?4MXhSBt}{UlLWOz*wS#p(!#6<3U@xc}e~4 znHkWBhm|c3K+d!yyGaV~Q`KzA4`X@Sp>gPnV>*P8djyc{<4X2^!241dm!{#^dp3=S z;LpjY@So|F{im35WCI0e60rFHSF_q@CF$MMU$Iyb@Z6ECjjFs(7rkw(>@k%s$jYnH z>`Ur45~M1gffGVxU7^hjW=k-ufhjrCM5cQaJkip0|MO04Q06o?$f5)n6s8I_u{giv z?)Jx{?|W{uGY_pjI%8wMYpM&WPxnUeE7!+%uFD;lt2(trNJ!-O-ubAt#s(Ft1Z7U& zkTg9=*Nh&~|A*M~W(X;DzLCL7)K0;Vse zw_yhCjpCBVe}gP|T0$_pKSXdzwl_%d)SbfKXlr4+BQZy9i@e#~MUMYk=o6-MsogVw zgh-w699&r*Apt?f#VbPqi|_E-O|H%fwCe+uPMk_8~Xx%*)SYMLJBq$a0r8>sqi%_!Un2n>v1k z@tqau4zs|%LG^3l&l;Uu98KLvMe5mS48^YFc#aUGYQ9DRHRhB=mbq5NAJsphTrbp$ z>%M3QNz!KE9cC8FCM+Tlw~H zRNf(IxwvdK7m)-qEw2((t9H{aSD}__Dor)2(V1D#nMiB;>^}PtR+QO; z-i^ZbL^;vH_I!cXcOgxWxPdx?Orf}-Ho?h5G~IpJzoo?GA;V=O&^62=IN2a zVymV``h~Il1G*~dS(tw%^mLV6T;yFHddlIkn9~TAG+Mi+<%cFmFPAKfg&FO&8;aFD zB_zrJUiJdKfMh`UZaeckDvh>RDa!Aa9v{H*GdDZtKh81BCr>cOb+4`L%WmqV=%0DR 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 z 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

*^4`7W7X5vWBImQzi1P_GKKzsQM{UvGI}N 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 H488vc6e7rX literal 81040 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 diff --git a/assets/opensb/interface/title/starbound.png b/assets/opensb/interface/title/starbound.png index 24ea4d44e91f14af0921bbca171bd0a4ae1ffe5b..33647cc84753505ef34bf899ab4808481a5a0420 100644 GIT binary patch literal 76785 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�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 DgDtW0 literal 80794 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

    YCYWq@R33jj+QBp?1jfj-ts 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 diff --git a/assets/opensb/items/tools/inspectiontool/inspectionmodeicon.png b/assets/opensb/items/tools/inspectiontool/inspectionmodeicon.png index 2ba0112dda6842125a5e18b3b74ba98280221484..b110a66f3af3a67e5f475ab59fb38663e454b5dc 100644 GIT binary patch delta 150 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 I6NmTz2PxL2(f|Me diff --git a/assets/opensb/rendering/sprites/error_left.png b/assets/opensb/rendering/sprites/error_left.png index 2f4ec6fc438a363f43529870258c16b7a16d3853..a2cf6b6ee5d6556f187628b79d6702bf86305912 100644 GIT binary patch delta 121 zcmV-<0EYjv0i*$tGICu>L_t(|+U=472Eb4ZLv#O2N>S5%o?$50j zF1<5g8xD~y_&yqE$OdE|d;|Q!Gy#z8scS&8&cW94x5&Gop99GLIdJ>+FaawEoYH*& bs#=i?O~hC(3Hmi?00000NkvXXu0mjf>VGvX delta 136 zcmV;30C)eS0kQ#*GJk7HL_t(|+U=524!|G?Lwo;AaWuBLK>=B^ACi5{L`m@}ngU%z zu2o`c1*J~@dTZS8 qgVWuksX0PZlpBiY&mc5cJpfI_ST2oT%`*T1002ovPDHLkU;%=6$~@`- diff --git a/assets/opensb/rendering/sprites/error_right.png b/assets/opensb/rendering/sprites/error_right.png index 1fadd17dbd205e8152af38204baf366cad7319da..d7c882037b2593cc09006a2b49cdcdf86bf1394a 100644 GIT binary patch delta 125 zcmV-@0D}Ln0jL3xGIn7}L_t(|+U(MS2Eb4Vh2iu5FV&;nan>&)Gla2`I{7fVia7r6 zMwC4DT<{RtlMV4+(kXJmoQM9y1=ueGbe?Vd%GJI!AL_t(|+U=A}3IHGoM7{r|Jeq-@8l|8`ErNowkp~(h5wqyB zKrV^wR&@s@WaPWng!7t&D5w!MdJ#W(9<0s;m|U-3V};@MHW;O6ZMnV;mW{7|4!l1- lg2RDcXOOe!OAx*kJsLJOSS~pX*1`Y)002ovPDHLkV1jw(Hkkkb diff --git a/assets/opensb/sky/orbitals/orangestar.png b/assets/opensb/sky/orbitals/orangestar.png index 788a070c13dd4e6b9933737b00e4c3ebb4b61a96..b2ea72e8c0e8d971dddd6488fcd0c84412cea099 100644 GIT binary patch literal 10407 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 z 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 WELdh={0a5|00006?aD6UB;#V$onsiaQSU7 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 literal 10804 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 diff --git a/assets/opensb/sky/orbitals/yellowstar.png b/assets/opensb/sky/orbitals/yellowstar.png index 596d8ef45b323f1b07f5099d8145bcc62325118b..8979000ca84124c12fcb333c4bad61b5a5a8a84e 100644 GIT binary patch literal 10513 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 T?sLaa00000NkvXXu0mjfr7f+1 literal 10778 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 Y0|T3bPYhfx(*OVf07*qoM6N<$f-9L!wEzGB diff --git a/assets/opensb/tiles/shadows.png b/assets/opensb/tiles/shadows.png index 28bb7a30cc8e6b5e5a25448a2487a35744642509..af4df9ed3c792180474631176503d7dafa621785 100644 GIT binary patch delta 127 zcmV-_0D%9d0g(Za8F&N$008j3ai9PI09Z*xK~#9!-IB2lz%UHMbb!wA9sU2T&SikQ zTuY6S69RF19ho*CXglnm=UL$E=^#>wZ8p3R&_aFhXdz;SvhaVQ0xPtAsTZ1OtkAaf hT8INyi1%@xxdE|zD2e>7Fq8lQ002ovPDHLkV1n#pIL810 delta 149 zcmV;G0BZk{0j2?v8Gi-<003IGxhntw0BuP`K~#9!W8mT8u_FSj05J~(l>iR}sE}(u zvVJPK1+U*3pcdi7v<@J$%!Zjkj{qVBXdOU2l$b;F03y-=ngtNU0E5v08t4Eblt1ZE z$nsDaQ8W)AyoEd+0*InQo*n^2vIR7#rpaz55W)ZgygA7_j1D4{00000NkvXXu0mjf DoT@bI From 0a1a82b18b86362263c8fa9ce8919c6d3b36d85c Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 26 Dec 2024 20:53:06 +1100 Subject: [PATCH 117/181] Head Rotation (way too hardcoded, not ideal but it will do in the meantime as many have been asking for it) --- .../optionsmenu/optionsmenu.config.patch | 20 ++++++- source/frontend/StarOptionsMenu.cpp | 15 ++++- source/frontend/StarOptionsMenu.hpp | 2 + source/game/StarHumanoid.cpp | 55 ++++++++++++++++--- source/game/StarHumanoid.hpp | 7 +++ source/game/StarPlayer.cpp | 42 ++++++++++++-- 6 files changed, 126 insertions(+), 15 deletions(-) diff --git a/assets/opensb/interface/optionsmenu/optionsmenu.config.patch b/assets/opensb/interface/optionsmenu/optionsmenu.config.patch index a169bef..4755b45 100644 --- a/assets/opensb/interface/optionsmenu/optionsmenu.config.patch +++ b/assets/opensb/interface/optionsmenu/optionsmenu.config.patch @@ -54,6 +54,24 @@ "instrumentSlider" : { "type" : "slider", "position" : [62, 158], "gridImage" : "/interface/optionsmenu/largeselection.png" }, "instrumentLabel" : { "type" : "label", "position" : [32, 158], "value" : "Tunes" }, - "instrumentValueLabel" : { "type" : "label", "position" : [192, 158], "hAnchor" : "mid", "value" : "Replace Me" } + "instrumentValueLabel" : { "type" : "label", "position" : [192, 158], "hAnchor" : "mid", "value" : "Replace Me" }, + + "headRotationLabel" : { + "type" : "label", + "position" : [25, 51], + "hAnchor" : "left", + "value" : "HEAD ROTATION" + }, + "headRotationCheckbox" : { + "type" : "button", + "pressedOffset" : [0, 0], + "position" : [104, 51], + "base" : "/interface/optionsmenu/checkboxnocheck.png", + "hover" : "/interface/optionsmenu/checkboxnocheckhover.png", + "baseImageChecked" : "/interface/optionsmenu/checkboxcheck.png", + "hoverImageChecked" : "/interface/optionsmenu/checkboxcheckhover.png", + "checkable" : true, + "checked" : true + } } } \ No newline at end of file diff --git a/source/frontend/StarOptionsMenu.cpp b/source/frontend/StarOptionsMenu.cpp index 8253f1f..28d44f6 100644 --- a/source/frontend/StarOptionsMenu.cpp +++ b/source/frontend/StarOptionsMenu.cpp @@ -10,6 +10,7 @@ #include "StarVoiceSettingsMenu.hpp" #include "StarBindingsMenu.hpp" #include "StarGraphicsMenu.hpp" +#include "StarHumanoid.hpp" namespace Star { @@ -47,6 +48,9 @@ OptionsMenu::OptionsMenu(PaneManager* manager, UniverseClientPtr client) reader.registerCallback("allowAssetsMismatchCheckbox", [=](Widget*) { updateAllowAssetsMismatch(); }); + reader.registerCallback("headRotationCheckbox", [=](Widget*) { + updateHeadRotation(); + }); reader.registerCallback("backButton", [=](Widget*) { dismiss(); }); @@ -77,6 +81,7 @@ OptionsMenu::OptionsMenu(PaneManager* manager, UniverseClientPtr client) m_clientIPJoinableButton = fetchChild("clientIPJoinableCheckbox"); m_clientP2PJoinableButton = fetchChild("clientP2PJoinableCheckbox"); m_allowAssetsMismatchButton = fetchChild("allowAssetsMismatchCheckbox"); + m_headRotationButton = fetchChild("headRotationCheckbox"); m_instrumentLabel = fetchChild("instrumentValueLabel"); m_sfxLabel = fetchChild("sfxValueLabel"); @@ -115,7 +120,8 @@ StringList const OptionsMenu::ConfigKeys = { "tutorialMessages", "clientIPJoinable", "clientP2PJoinable", - "allowAssetsMismatch" + "allowAssetsMismatch", + "humanoidHeadRotation" }; void OptionsMenu::initConfig() { @@ -166,6 +172,12 @@ void OptionsMenu::updateAllowAssetsMismatch() { Root::singleton().configuration()->set("allowAssetsMismatch", m_allowAssetsMismatchButton->isChecked()); } +void OptionsMenu::updateHeadRotation() { + m_localChanges.set("humanoidHeadRotation", m_headRotationButton->isChecked()); + Root::singleton().configuration()->set("humanoidHeadRotation", m_headRotationButton->isChecked()); + Humanoid::globalHeadRotation() = m_headRotationButton->isChecked(); +} + void OptionsMenu::syncGuiToConf() { m_instrumentSlider->setVal(m_localChanges.get("instrumentVol").toInt(), false); m_instrumentLabel->setText(toString(m_instrumentSlider->val())); @@ -180,6 +192,7 @@ void OptionsMenu::syncGuiToConf() { m_clientIPJoinableButton->setChecked(m_localChanges.get("clientIPJoinable").toBool()); m_clientP2PJoinableButton->setChecked(m_localChanges.get("clientP2PJoinable").toBool()); m_allowAssetsMismatchButton->setChecked(m_localChanges.get("allowAssetsMismatch").toBool()); + m_headRotationButton->setChecked(m_localChanges.get("humanoidHeadRotation").optBool().value(true)); auto appController = GuiContext::singleton().applicationController(); if (!appController->p2pNetworkingService()) { diff --git a/source/frontend/StarOptionsMenu.hpp b/source/frontend/StarOptionsMenu.hpp index 9fde1ac..4a28fd0 100644 --- a/source/frontend/StarOptionsMenu.hpp +++ b/source/frontend/StarOptionsMenu.hpp @@ -36,6 +36,7 @@ private: void updateClientIPJoinable(); void updateClientP2PJoinable(); void updateAllowAssetsMismatch(); + void updateHeadRotation(); void syncGuiToConf(); @@ -52,6 +53,7 @@ private: ButtonWidgetPtr m_clientIPJoinableButton; ButtonWidgetPtr m_clientP2PJoinableButton; ButtonWidgetPtr m_allowAssetsMismatchButton; + ButtonWidgetPtr m_headRotationButton; LabelWidgetPtr m_instrumentLabel; LabelWidgetPtr m_sfxLabel; diff --git a/source/game/StarHumanoid.cpp b/source/game/StarHumanoid.cpp index c71e161..8f39abe 100644 --- a/source/game/StarHumanoid.cpp +++ b/source/game/StarHumanoid.cpp @@ -242,6 +242,14 @@ EnumMap const Humanoid::StateNames{ {Humanoid::State::Lay, "lay"}, }; +// gross, but I don't want to make config calls more than I need to +bool& Humanoid::globalHeadRotation(Maybe default) { + static Maybe s_headRotation; + if (!s_headRotation) + s_headRotation = Root::singleton().configuration()->get("humanoidHeadRotation").optBool().value(true); + return *s_headRotation; +}; + Humanoid::Humanoid(Json const& config) { loadConfig(config); @@ -252,7 +260,7 @@ Humanoid::Humanoid(Json const& config) { m_movingBackwards = false; m_altHand.angle = 0; m_facingDirection = Direction::Left; - m_rotation = 0; + m_headRotationTarget = m_headRotation = m_rotation = 0; m_scale = Vec2F::filled(1.f); m_drawVaporTrail = false; m_state = State::Idle; @@ -412,6 +420,10 @@ void Humanoid::setMovingBackwards(bool movingBackwards) { m_movingBackwards = movingBackwards; } +void Humanoid::setHeadRotation(float headRotation) { + m_headRotationTarget = headRotation; +} + void Humanoid::setRotation(float rotation) { m_rotation = rotation; } @@ -476,6 +488,10 @@ void Humanoid::setPrimaryHandNonRotatedDrawables(List drawables) { m_primaryHand.nonRotatedDrawables = std::move(drawables); } +bool Humanoid::primaryHandHoldingItem() const { + return m_primaryHand.holdingItem; +} + void Humanoid::setAltHandParameters(bool holdingItem, float angle, float itemAngle, bool recoil, bool outsideOfHand) { m_altHand.holdingItem = holdingItem; @@ -498,16 +514,24 @@ void Humanoid::setAltHandNonRotatedDrawables(List drawables) { m_altHand.nonRotatedDrawables = std::move(drawables); } +bool Humanoid::altHandHoldingItem() const { + return m_altHand.holdingItem; +} + void Humanoid::animate(float dt) { m_animationTimer += dt; m_emoteAnimationTimer += dt; m_danceTimer += dt; + float headRotationTarget = globalHeadRotation() ? m_headRotationTarget : 0.f; + float diff = angleDiff(m_headRotation, headRotationTarget); + m_headRotation = (headRotationTarget - (headRotationTarget - m_headRotation) * powf(.333333f, dt * 60.f)); } void Humanoid::resetAnimation() { m_animationTimer = 0.0f; m_emoteAnimationTimer = 0.0f; m_danceTimer = 0.0f; + m_headRotation = globalHeadRotation() ? 0.f : m_headRotationTarget; } List Humanoid::render(bool withItems, bool withRotationAndScale) { @@ -641,11 +665,28 @@ List Humanoid::render(bool withItems, bool withRotationAndScale) { else if (m_state == Lay) headPosition += m_headLayOffset; + auto addHeadDrawable = [&](Drawable drawable, bool forceFullbright = false) { + if (m_facingDirection == Direction::Left) + drawable.scale(Vec2F(-1, 1)); + drawable.fullbright |= forceFullbright; + if (m_headRotation != 0.f) { + float dir = numericalDirection(m_facingDirection); + Vec2F rotationPoint = headPosition; + rotationPoint[0] *= dir; + rotationPoint[1] -= .25f; + float headX = (m_headRotation / ((float)Constants::pi * 2.f)); + drawable.rotate(m_headRotation, rotationPoint); + drawable.position[0] -= state() == State::Run ? (fmaxf(headX * dir, 0.f) * 2.f) * dir : headX; + drawable.position[1] -= fabsf(m_headRotation / ((float)Constants::pi * 4.f)); + } + drawables.append(std::move(drawable)); + }; + if (!m_headFrameset.empty() && !m_bodyHidden) { String image = strf("{}:normal", m_headFrameset); auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, headPosition); drawable.imagePart().addDirectives(getBodyDirectives(), true); - addDrawable(std::move(drawable), m_bodyFullbright); + addHeadDrawable(std::move(drawable), m_bodyFullbright); } if (!m_emoteFrameset.empty() && !m_bodyHidden) { @@ -653,14 +694,14 @@ List Humanoid::render(bool withItems, bool withRotationAndScale) { String image = strf("{}:{}.{}{}", m_emoteFrameset, emoteFrameBase(m_emoteState), emoteStateSeq, emoteDirectives.prefix()); auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, headPosition); drawable.imagePart().addDirectives(emoteDirectives, true); - addDrawable(std::move(drawable), m_bodyFullbright); + addHeadDrawable(std::move(drawable), m_bodyFullbright); } if (!m_hairFrameset.empty() && !m_bodyHidden) { String image = strf("{}:normal", m_hairFrameset); auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, headPosition); drawable.imagePart().addDirectives(getHairDirectives(), true).addDirectives(getHelmetMaskDirectives(), true); - addDrawable(std::move(drawable), m_bodyFullbright); + addHeadDrawable(std::move(drawable), m_bodyFullbright); } if (!m_bodyFrameset.empty() && !m_bodyHidden) { @@ -719,21 +760,21 @@ List Humanoid::render(bool withItems, bool withRotationAndScale) { String image = strf("{}:normal", m_facialHairFrameset); auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, headPosition); drawable.imagePart().addDirectives(getFacialHairDirectives(), true).addDirectives(getHelmetMaskDirectives(), true); - addDrawable(std::move(drawable), m_bodyFullbright); + addHeadDrawable(std::move(drawable), m_bodyFullbright); } if (!m_facialMaskFrameset.empty() && !m_bodyHidden) { String image = strf("{}:normal", m_facialMaskFrameset); auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, headPosition); drawable.imagePart().addDirectives(getFacialMaskDirectives(), true).addDirectives(getHelmetMaskDirectives(), true); - addDrawable(std::move(drawable)); + addHeadDrawable(std::move(drawable)); } if (!m_headArmorFrameset.empty()) { String image = strf("{}:normal{}", m_headArmorFrameset, m_headArmorDirectives.prefix()); auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, headPosition); drawable.imagePart().addDirectives(getHeadDirectives(), true); - addDrawable(std::move(drawable)); + addHeadDrawable(std::move(drawable)); } auto frontArmDrawable = [&](String const& frameSet, Directives const& directives) -> Drawable { diff --git a/source/game/StarHumanoid.hpp b/source/game/StarHumanoid.hpp index c83ddb5..6fd1cbe 100644 --- a/source/game/StarHumanoid.hpp +++ b/source/game/StarHumanoid.hpp @@ -100,6 +100,8 @@ public: }; static EnumMap const StateNames; + static bool& globalHeadRotation(Maybe default = {}); + Humanoid(Json const& config); Humanoid(HumanoidIdentity const& identity); Humanoid(Humanoid const&) = default; @@ -163,6 +165,7 @@ public: void setDance(Maybe const& dance); void setFacingDirection(Direction facingDirection); void setMovingBackwards(bool movingBackwards); + void setHeadRotation(float headRotation); void setRotation(float rotation); void setScale(Vec2F scale); @@ -183,6 +186,7 @@ public: void setPrimaryHandFrameOverrides(String backFrameOverride, String frontFrameOverride); void setPrimaryHandDrawables(List drawables); void setPrimaryHandNonRotatedDrawables(List drawables); + bool primaryHandHoldingItem() const; // Same as primary hand. void setAltHandParameters(bool holdingItem, float angle, float itemAngle, bool recoil, @@ -190,6 +194,7 @@ public: void setAltHandFrameOverrides(String backFrameOverride, String frontFrameOverride); void setAltHandDrawables(List drawables); void setAltHandNonRotatedDrawables(List drawables); + bool altHandHoldingItem() const; // Updates the animation based on whatever the current animation state is, // wrapping or clamping animation time as appropriate. @@ -355,6 +360,8 @@ private: Maybe m_dance; Direction m_facingDirection; bool m_movingBackwards; + float m_headRotation; + float m_headRotationTarget; float m_rotation; Vec2F m_scale; bool m_drawVaporTrail; diff --git a/source/game/StarPlayer.cpp b/source/game/StarPlayer.cpp index 2f89ff3..24a3c16 100644 --- a/source/game/StarPlayer.cpp +++ b/source/game/StarPlayer.cpp @@ -1021,16 +1021,16 @@ void Player::update(float dt, uint64_t) { || m_humanoid->danceCyclicOrEnded() || m_movementController->running()) m_humanoid->setDance({}); + m_tools->suppressItems(suppressedItems); + m_tools->tick(dt, m_shifting, m_pendingMoves); + + if (auto overrideFacingDirection = m_tools->setupHumanoidHandItems(*m_humanoid, position(), aimPosition())) + m_movementController->controlFace(*overrideFacingDirection); + bool isClient = world()->isClient(); if (isClient) m_armor->setupHumanoidClothingDrawables(*m_humanoid, forceNude()); - m_tools->suppressItems(suppressedItems); - m_tools->tick(dt, m_shifting, m_pendingMoves); - - if (auto overrideFacingDirection = m_tools->setupHumanoidHandItems(*m_humanoid, position(), aimPosition())) - m_movementController->controlFace(*overrideFacingDirection); - m_effectsAnimator->resetTransformationGroup("flip"); if (m_movementController->facingDirection() == Direction::Left) m_effectsAnimator->scaleTransformationGroup("flip", Vec2F(-1, 1)); @@ -1075,6 +1075,35 @@ void Player::update(float dt, uint64_t) { m_effectEmitter->tick(dt, *entityMode()); + if (isClient) { + bool calculateHeadRotation = isMaster(); + if (!calculateHeadRotation) { + auto headRotationProperty = getSecretProperty("humanoid.headRotation"); + if (headRotationProperty.isType(Json::Type::Float)) { + m_humanoid->setHeadRotation(headRotationProperty.toFloat()); + } else + calculateHeadRotation = true; + } + if (calculateHeadRotation) { // master or not an OpenStarbound player + float headRotation = 0.f; + if (m_humanoid->primaryHandHoldingItem() || m_humanoid->altHandHoldingItem()) { + auto primary = m_tools->primaryHandItem(); + auto alt = m_tools->altHandItem(); + String const disableFlag = "disableHeadRotation"; + auto statusFlag = m_statusController->statusProperty(disableFlag); + if (!(statusFlag.isType(Json::Type::Bool) && statusFlag.toBool()) + && !(primary && primary->instanceValue(disableFlag)) + && !(alt && alt->instanceValue(disableFlag))) { + auto diff = world()->geometry().diff(aimPosition(), mouthPosition()); + diff.setX(fabsf(diff.x())); + headRotation = diff.angle() * .25f * numericalDirection(m_humanoid->facingDirection()); + } + } + m_humanoid->setHeadRotation(headRotation); + setSecretProperty("humanoid.headRotation", headRotation); + } + } + m_humanoid->setFacingDirection(m_movementController->facingDirection()); m_humanoid->setMovingBackwards(m_movementController->facingDirection() != m_movementController->movingDirection()); @@ -2610,6 +2639,7 @@ Maybe Player::getSecretPropertyView(String const& name) const { return {}; } + Json Player::getSecretProperty(String const& name, Json defaultValue) const { if (auto tag = m_effectsAnimator->globalTagPtr(secretProprefix + name)) { DataStreamExternalBuffer buffer(tag->utf8Ptr(), tag->utf8Size()); From e092de711e559dedb582c32d1bb248aaca6e4315 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 26 Dec 2024 21:00:29 +1100 Subject: [PATCH 118/181] fix compile error --- source/game/StarHumanoid.cpp | 2 +- source/game/StarHumanoid.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/game/StarHumanoid.cpp b/source/game/StarHumanoid.cpp index 8f39abe..97b90cd 100644 --- a/source/game/StarHumanoid.cpp +++ b/source/game/StarHumanoid.cpp @@ -243,7 +243,7 @@ EnumMap const Humanoid::StateNames{ }; // gross, but I don't want to make config calls more than I need to -bool& Humanoid::globalHeadRotation(Maybe default) { +bool& Humanoid::globalHeadRotation() { static Maybe s_headRotation; if (!s_headRotation) s_headRotation = Root::singleton().configuration()->get("humanoidHeadRotation").optBool().value(true); diff --git a/source/game/StarHumanoid.hpp b/source/game/StarHumanoid.hpp index 6fd1cbe..98412f2 100644 --- a/source/game/StarHumanoid.hpp +++ b/source/game/StarHumanoid.hpp @@ -100,7 +100,7 @@ public: }; static EnumMap const StateNames; - static bool& globalHeadRotation(Maybe default = {}); + static bool& globalHeadRotation(); Humanoid(Json const& config); Humanoid(HumanoidIdentity const& identity); From 1210a75fb72bc37dd1b894ca7cb0ca0d636b5ac5 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 26 Dec 2024 22:12:44 +1100 Subject: [PATCH 119/181] ! Fix head rotation not showing on other players --- source/game/StarPlayer.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source/game/StarPlayer.cpp b/source/game/StarPlayer.cpp index 24a3c16..48368ec 100644 --- a/source/game/StarPlayer.cpp +++ b/source/game/StarPlayer.cpp @@ -1021,16 +1021,16 @@ void Player::update(float dt, uint64_t) { || m_humanoid->danceCyclicOrEnded() || m_movementController->running()) m_humanoid->setDance({}); + bool isClient = world()->isClient(); + if (isClient) + m_armor->setupHumanoidClothingDrawables(*m_humanoid, forceNude()); + m_tools->suppressItems(suppressedItems); m_tools->tick(dt, m_shifting, m_pendingMoves); if (auto overrideFacingDirection = m_tools->setupHumanoidHandItems(*m_humanoid, position(), aimPosition())) m_movementController->controlFace(*overrideFacingDirection); - bool isClient = world()->isClient(); - if (isClient) - m_armor->setupHumanoidClothingDrawables(*m_humanoid, forceNude()); - m_effectsAnimator->resetTransformationGroup("flip"); if (m_movementController->facingDirection() == Direction::Left) m_effectsAnimator->scaleTransformationGroup("flip", Vec2F(-1, 1)); @@ -1100,7 +1100,8 @@ void Player::update(float dt, uint64_t) { } } m_humanoid->setHeadRotation(headRotation); - setSecretProperty("humanoid.headRotation", headRotation); + if (isMaster()) + setSecretProperty("humanoid.headRotation", headRotation); } } From 3205f3b2831eba410b96727d2bae33205689ea96 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Fri, 27 Dec 2024 08:47:40 +1100 Subject: [PATCH 120/181] fix item inventoryFilters handling --- assets/opensb/player.config.patch | 2 ++ source/game/StarPlayerInventory.cpp | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/assets/opensb/player.config.patch b/assets/opensb/player.config.patch index 5960507..bd5cbc8 100644 --- a/assets/opensb/player.config.patch +++ b/assets/opensb/player.config.patch @@ -12,5 +12,7 @@ "maxWireTrans" : 0.4 }, + "inventoryFilters" : { "default" : {} }, + "swapDance" : null // Set this to a valid dance to trigger on character swap. } \ No newline at end of file diff --git a/source/game/StarPlayerInventory.cpp b/source/game/StarPlayerInventory.cpp index 0fed167..4b9cff2 100644 --- a/source/game/StarPlayerInventory.cpp +++ b/source/game/StarPlayerInventory.cpp @@ -947,14 +947,14 @@ bool PlayerInventory::checkInventoryFilter(ItemPtr const& items, String const& f auto itemFilters = items->instanceValue("inventoryFilters"); if (itemFilters.isType(Json::Type::Object)) { - filterConfig = itemFilters.get(filterName); + filterConfig = itemFilters.opt(filterName).value(); if (!filterConfig.isType(Json::Type::Object)) - filterConfig = itemFilters.get("default"); + filterConfig = itemFilters.opt("default").value(); } if (!filterConfig.isType(Json::Type::Object)) { auto config = Root::singleton().assets()->json("/player.config:inventoryFilters"); - filterConfig = config.get(filterName); + filterConfig = config.opt(filterName).value(); if (!filterConfig.isType(Json::Type::Object)) filterConfig = config.get("default"); } From 5cf11ead986b950a9932fae667805fd71d79fa72 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Fri, 27 Dec 2024 20:14:36 +1100 Subject: [PATCH 121/181] temporary /render cmd for debugging --- source/frontend/StarClientCommandProcessor.cpp | 11 ++++++++++- source/frontend/StarClientCommandProcessor.hpp | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/source/frontend/StarClientCommandProcessor.cpp b/source/frontend/StarClientCommandProcessor.cpp index e0fe827..5b2ca0f 100644 --- a/source/frontend/StarClientCommandProcessor.cpp +++ b/source/frontend/StarClientCommandProcessor.cpp @@ -52,7 +52,8 @@ ClientCommandProcessor::ClientCommandProcessor(UniverseClientPtr universeClient, {"enabletech", bind(&ClientCommandProcessor::enableTech, this, _1)}, {"upgradeship", bind(&ClientCommandProcessor::upgradeShip, this, _1)}, {"swap", bind(&ClientCommandProcessor::swap, this, _1)}, - {"respawnInWorld", bind(&ClientCommandProcessor::respawnInWorld, this, _1)} + {"respawnInWorld", bind(&ClientCommandProcessor::respawnInWorld, this, _1)}, + {"render", bind(&ClientCommandProcessor::render, this, _1)} }; } @@ -440,4 +441,12 @@ String ClientCommandProcessor::respawnInWorld(String const& argumentsString) { return strf("Respawn in this world set to {} (This is client-side!)", respawnInWorld ? "true" : "false"); } +// Temporary hardcoded render command for debugging purposes, future version will write to the clipboard +String ClientCommandProcessor::render(String const& imagePath) { + auto image = Root::singleton().assets()->image(imagePath); + image->writePng(File::open("render.png", IOMode::Write)); + return strf("Saved {}x{} image to render.png", image->width(), image->height()); +} + + } \ No newline at end of file diff --git a/source/frontend/StarClientCommandProcessor.hpp b/source/frontend/StarClientCommandProcessor.hpp index 94dad5d..c3978a4 100644 --- a/source/frontend/StarClientCommandProcessor.hpp +++ b/source/frontend/StarClientCommandProcessor.hpp @@ -59,6 +59,7 @@ private: String upgradeShip(String const& argumentsString); String swap(String const& argumentsString); String respawnInWorld(String const& argumentsString); + String render(String const& imagePath); UniverseClientPtr m_universeClient; CinematicPtr m_cinematicOverlay; From 8f1cadbbf2f0ad7b13f300bc50d039738e43352d Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Fri, 27 Dec 2024 21:08:41 +1100 Subject: [PATCH 122/181] enable hardened runtime on macOS builds --- source/client/CMakeLists.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source/client/CMakeLists.txt b/source/client/CMakeLists.txt index a6773d3..474f2f8 100644 --- a/source/client/CMakeLists.txt +++ b/source/client/CMakeLists.txt @@ -31,12 +31,16 @@ ADD_EXECUTABLE (starbound WIN32 $ $ $ $ ${star_client_HEADERS} ${star_client_SOURCES} ${star_client_RESOURCES}) -IF(STAR_PRECOMPILED_HEADERS) +IF (STAR_PRECOMPILED_HEADERS) TARGET_PRECOMPILE_HEADERS (starbound REUSE_FROM star_core) ENDIF() -IF(UNIX) - set_target_properties (starbound PROPERTIES LINK_FLAGS "-Wl,-rpath,'$ORIGIN'") +IF (UNIX) + SET_TARGET_PROPERTIES (starbound PROPERTIES LINK_FLAGS "-Wl,-rpath,'$ORIGIN'") +ENDIF() + +IF (STAR_SYSTEM_MACOS) + SET_TARGET_PROPERTIES (starbound PROPERTIES XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME YES) ENDIF() TARGET_LINK_LIBRARIES (starbound ${STAR_EXT_LIBS} ${STAR_EXT_GUI_LIBS}) From 45c89cefb602471a9db232b9d80a75444081feac Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Fri, 27 Dec 2024 21:54:59 +1100 Subject: [PATCH 123/181] Update StarImageProcessing.cpp --- source/core/StarImageProcessing.cpp | 23 ++++++++--------------- source/core/StarImageProcessing.hpp | 6 +++--- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/source/core/StarImageProcessing.cpp b/source/core/StarImageProcessing.cpp index 390f600..938bbe9 100644 --- a/source/core/StarImageProcessing.cpp +++ b/source/core/StarImageProcessing.cpp @@ -10,11 +10,7 @@ namespace Star { -Image scaleNearest(Image const& srcImage, Vec2F scale) { - if (scale[0] < 0.0f || scale[1] < 0.0f) { - Logger::warn("Negative scale in scaleNearest({})", scale); - scale = scale.piecewiseMax(Vec2F::filled(0.f)); - } +Image scaleNearest(Image const& srcImage, Vec2F const& scale) { Vec2U srcSize = srcImage.size(); Vec2U destSize = Vec2U::round(vmult(Vec2F(srcSize), scale)); destSize[0] = max(destSize[0], 1u); @@ -29,11 +25,7 @@ Image scaleNearest(Image const& srcImage, Vec2F scale) { return destImage; } -Image scaleBilinear(Image const& srcImage, Vec2F scale) { - if (scale[0] < 0.0f || scale[1] < 0.0f) { - Logger::warn("Negative scale in scaleBilinear({})", scale); - scale = scale.piecewiseMax(Vec2F::filled(0.f)); - } +Image scaleBilinear(Image const& srcImage, Vec2F const& scale) { Vec2U srcSize = srcImage.size(); Vec2U destSize = Vec2U::round(vmult(Vec2F(srcSize), scale)); destSize[0] = max(destSize[0], 1u); @@ -57,11 +49,7 @@ Image scaleBilinear(Image const& srcImage, Vec2F scale) { return destImage; } -Image scaleBicubic(Image const& srcImage, Vec2F scale) { - if (scale[0] < 0.0f || scale[1] < 0.0f) { - Logger::warn("Negative scale in scaleBicubic({})", scale); - scale = scale.piecewiseMax(Vec2F::filled(0.f)); - } +Image scaleBicubic(Image const& srcImage, Vec2F const& scale) { Vec2U srcSize = srcImage.size(); Vec2U destSize = Vec2U::round(vmult(Vec2F(srcSize), scale)); destSize[0] = max(destSize[0], 1u); @@ -631,6 +619,11 @@ void processImageOperation(ImageOperation const& operation, Image& image, ImageR image = borderImage; } else if (auto op = operation.ptr()) { + auto scale = op->scale; + if (scale[0] < 0.0f || scale[1] < 0.0f) { + Logger::warn("Negative scale in ScaleImageOperation ({})", scale); + scale = scale.piecewiseMax(Vec2F::filled(0.f)); + } if (op->mode == ScaleImageOperation::Nearest) image = scaleNearest(image, op->scale); else if (op->mode == ScaleImageOperation::Bilinear) diff --git a/source/core/StarImageProcessing.hpp b/source/core/StarImageProcessing.hpp index 4022d38..8316d18 100644 --- a/source/core/StarImageProcessing.hpp +++ b/source/core/StarImageProcessing.hpp @@ -10,9 +10,9 @@ STAR_CLASS(Image); STAR_EXCEPTION(ImageOperationException, StarException); -Image scaleNearest(Image const& srcImage, Vec2F scale); -Image scaleBilinear(Image const& srcImage, Vec2F scale); -Image scaleBicubic(Image const& srcImage, Vec2F scale); +Image scaleNearest(Image const& srcImage, Vec2F const& scale); +Image scaleBilinear(Image const& srcImage, Vec2F const& scale); +Image scaleBicubic(Image const& srcImage, Vec2F const& scale); StringList colorDirectivesFromConfig(JsonArray const& directives); String paletteSwapDirectivesFromConfig(Json const& swaps); From aba77ed2b434e5aa953b553fc71f70cea34de290 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Fri, 27 Dec 2024 22:06:33 +1100 Subject: [PATCH 124/181] Update StarImageProcessing.cpp [skip ci] --- source/core/StarImageProcessing.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/core/StarImageProcessing.cpp b/source/core/StarImageProcessing.cpp index 938bbe9..9f64124 100644 --- a/source/core/StarImageProcessing.cpp +++ b/source/core/StarImageProcessing.cpp @@ -625,11 +625,11 @@ void processImageOperation(ImageOperation const& operation, Image& image, ImageR scale = scale.piecewiseMax(Vec2F::filled(0.f)); } if (op->mode == ScaleImageOperation::Nearest) - image = scaleNearest(image, op->scale); + image = scaleNearest(image, scale); else if (op->mode == ScaleImageOperation::Bilinear) - image = scaleBilinear(image, op->scale); + image = scaleBilinear(image, scale); else if (op->mode == ScaleImageOperation::Bicubic) - image = scaleBicubic(image, op->scale); + image = scaleBicubic(image, scale); } else if (auto op = operation.ptr()) { image = image.subImage(Vec2U(op->subset.min()), Vec2U(op->subset.size())); From 10edbdc399a52958f59ee0d8b9cc216a1bcb1441 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sat, 28 Dec 2024 10:29:47 +1100 Subject: [PATCH 125/181] disable GCC unmath optimization in non-nearest scaling funcs --- source/core/StarImageProcessing.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/core/StarImageProcessing.cpp b/source/core/StarImageProcessing.cpp index 9f64124..d599c2c 100644 --- a/source/core/StarImageProcessing.cpp +++ b/source/core/StarImageProcessing.cpp @@ -25,6 +25,8 @@ Image scaleNearest(Image const& srcImage, Vec2F const& scale) { return destImage; } +#pragma GCC push_options +#pragma GCC optimize("-fno-unsafe-math-optimizations") Image scaleBilinear(Image const& srcImage, Vec2F const& scale) { Vec2U srcSize = srcImage.size(); Vec2U destSize = Vec2U::round(vmult(Vec2F(srcSize), scale)); @@ -100,6 +102,7 @@ Image scaleBicubic(Image const& srcImage, Vec2F const& scale) { return destImage; } +#pragma GCC pop_options StringList colorDirectivesFromConfig(JsonArray const& directives) { List result; From 81dfda9ea0a4049d141d6af9534255ee4611de8a Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sat, 28 Dec 2024 10:46:37 +1100 Subject: [PATCH 126/181] Update StarImageProcessing.cpp --- source/core/StarImageProcessing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/StarImageProcessing.cpp b/source/core/StarImageProcessing.cpp index d599c2c..983ec4e 100644 --- a/source/core/StarImageProcessing.cpp +++ b/source/core/StarImageProcessing.cpp @@ -26,7 +26,7 @@ Image scaleNearest(Image const& srcImage, Vec2F const& scale) { } #pragma GCC push_options -#pragma GCC optimize("-fno-unsafe-math-optimizations") +#pragma GCC optimize("-O3") Image scaleBilinear(Image const& srcImage, Vec2F const& scale) { Vec2U srcSize = srcImage.size(); Vec2U destSize = Vec2U::round(vmult(Vec2F(srcSize), scale)); From 9da08e898d9c666f655c7f901d0c67b17a746608 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sat, 28 Dec 2024 10:58:44 +1100 Subject: [PATCH 127/181] Update StarImageProcessing.cpp --- source/core/StarImageProcessing.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/core/StarImageProcessing.cpp b/source/core/StarImageProcessing.cpp index 983ec4e..96edc0b 100644 --- a/source/core/StarImageProcessing.cpp +++ b/source/core/StarImageProcessing.cpp @@ -26,7 +26,7 @@ Image scaleNearest(Image const& srcImage, Vec2F const& scale) { } #pragma GCC push_options -#pragma GCC optimize("-O3") +#pragma GCC optimize("-fno-unsafe-math-optimizations", "-ffloat-store") Image scaleBilinear(Image const& srcImage, Vec2F const& scale) { Vec2U srcSize = srcImage.size(); Vec2U destSize = Vec2U::round(vmult(Vec2F(srcSize), scale)); @@ -35,13 +35,17 @@ Image scaleBilinear(Image const& srcImage, Vec2F const& scale) { Image destImage(destSize, srcImage.pixelFormat()); + auto lerpVec = [](float const& offset, Vec4F f0, Vec4F f1) { + return f0 * (1 - offset) + f1 * (offset); + }; + for (unsigned y = 0; y < destSize[1]; ++y) { for (unsigned x = 0; x < destSize[0]; ++x) { auto pos = vdiv(Vec2F(x, y), scale); auto ipart = Vec2I::floor(pos); auto fpart = pos - Vec2F(ipart); - auto result = lerp(fpart[1], lerp(fpart[0], Vec4F(srcImage.clamp(ipart[0], ipart[1])), Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1]))), lerp(fpart[0], + auto result = lerpVec(fpart[1], lerpVec(fpart[0], Vec4F(srcImage.clamp(ipart[0], ipart[1])), Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1]))), lerpVec(fpart[0], Vec4F(srcImage.clamp(ipart[0], ipart[1] + 1)), Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1] + 1)))); destImage.set({x, y}, Vec4B(result)); From 6b49f382e3a9429e97bc47a9b3c18c3ca8feb65c Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sat, 28 Dec 2024 13:07:51 +1100 Subject: [PATCH 128/181] move image scaling functions to their own unit, as -O2 --- source/core/CMakeLists.txt | 6 ++ source/core/StarImageProcessing.cpp | 99 +---------------------------- source/core/StarImageProcessing.hpp | 4 -- source/core/StarImageScaling.cpp | 98 ++++++++++++++++++++++++++++ source/core/StarImageScaling.hpp | 8 +++ 5 files changed, 113 insertions(+), 102 deletions(-) create mode 100644 source/core/StarImageScaling.cpp create mode 100644 source/core/StarImageScaling.hpp diff --git a/source/core/CMakeLists.txt b/source/core/CMakeLists.txt index fa1d246..6deb473 100644 --- a/source/core/CMakeLists.txt +++ b/source/core/CMakeLists.txt @@ -41,6 +41,7 @@ SET (star_core_HEADERS StarIdMap.hpp StarImage.hpp StarImageProcessing.hpp + StarImageScaling.hpp StarInputEvent.hpp StarInterpolation.hpp StarRefPtr.hpp @@ -152,6 +153,7 @@ SET (star_core_SOURCES StarIODevice.cpp StarImage.cpp StarImageProcessing.cpp + StarImageScaling.cpp StarInputEvent.cpp StarJson.cpp StarJsonBuilder.cpp @@ -229,6 +231,10 @@ IF(STAR_PRECOMPILED_HEADERS) TARGET_PRECOMPILE_HEADERS (star_core PUBLIC StarPch.hpp) ENDIF() +IF(STAR_COMPILER STREQUAL "gnu") + SET_SOURCE_FILES_PROPERTIES(StarImageScaling.cpp PROPERTIES COMPILE_FLAGS "-O2") +ENDIF() + IF(STAR_USE_JEMALLOC AND JEMALLOC_IS_PREFIXED) SET_SOURCE_FILES_PROPERTIES(StarMemory.cpp PROPERTIES COMPILE_DEFINITIONS STAR_JEMALLOC_IS_PREFIXED diff --git a/source/core/StarImageProcessing.cpp b/source/core/StarImageProcessing.cpp index 96edc0b..1cfd847 100644 --- a/source/core/StarImageProcessing.cpp +++ b/source/core/StarImageProcessing.cpp @@ -1,4 +1,5 @@ #include "StarImageProcessing.hpp" +#include "StarImageScaling.hpp" #include "StarMatrix3.hpp" #include "StarInterpolation.hpp" #include "StarLexicalCast.hpp" @@ -10,104 +11,6 @@ namespace Star { -Image scaleNearest(Image const& srcImage, Vec2F const& scale) { - Vec2U srcSize = srcImage.size(); - Vec2U destSize = Vec2U::round(vmult(Vec2F(srcSize), scale)); - destSize[0] = max(destSize[0], 1u); - destSize[1] = max(destSize[1], 1u); - - Image destImage(destSize, srcImage.pixelFormat()); - - for (unsigned y = 0; y < destSize[1]; ++y) { - for (unsigned x = 0; x < destSize[0]; ++x) - destImage.set({x, y}, srcImage.clamp(Vec2I::round(vdiv(Vec2F(x, y), scale)))); - } - return destImage; -} - -#pragma GCC push_options -#pragma GCC optimize("-fno-unsafe-math-optimizations", "-ffloat-store") -Image scaleBilinear(Image const& srcImage, Vec2F const& scale) { - Vec2U srcSize = srcImage.size(); - Vec2U destSize = Vec2U::round(vmult(Vec2F(srcSize), scale)); - destSize[0] = max(destSize[0], 1u); - destSize[1] = max(destSize[1], 1u); - - Image destImage(destSize, srcImage.pixelFormat()); - - auto lerpVec = [](float const& offset, Vec4F f0, Vec4F f1) { - return f0 * (1 - offset) + f1 * (offset); - }; - - for (unsigned y = 0; y < destSize[1]; ++y) { - for (unsigned x = 0; x < destSize[0]; ++x) { - auto pos = vdiv(Vec2F(x, y), scale); - auto ipart = Vec2I::floor(pos); - auto fpart = pos - Vec2F(ipart); - - auto result = lerpVec(fpart[1], lerpVec(fpart[0], Vec4F(srcImage.clamp(ipart[0], ipart[1])), Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1]))), lerpVec(fpart[0], - Vec4F(srcImage.clamp(ipart[0], ipart[1] + 1)), Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1] + 1)))); - - destImage.set({x, y}, Vec4B(result)); - } - } - - return destImage; -} - -Image scaleBicubic(Image const& srcImage, Vec2F const& scale) { - Vec2U srcSize = srcImage.size(); - Vec2U destSize = Vec2U::round(vmult(Vec2F(srcSize), scale)); - destSize[0] = max(destSize[0], 1u); - destSize[1] = max(destSize[1], 1u); - - Image destImage(destSize, srcImage.pixelFormat()); - - for (unsigned y = 0; y < destSize[1]; ++y) { - for (unsigned x = 0; x < destSize[0]; ++x) { - auto pos = vdiv(Vec2F(x, y), scale); - auto ipart = Vec2I::floor(pos); - auto fpart = pos - Vec2F(ipart); - - Vec4F a = cubic4(fpart[0], - Vec4F(srcImage.clamp(ipart[0], ipart[1])), - Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1])), - Vec4F(srcImage.clamp(ipart[0] + 2, ipart[1])), - Vec4F(srcImage.clamp(ipart[0] + 3, ipart[1]))); - - Vec4F b = cubic4(fpart[0], - Vec4F(srcImage.clamp(ipart[0], ipart[1] + 1)), - Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1] + 1)), - Vec4F(srcImage.clamp(ipart[0] + 2, ipart[1] + 1)), - Vec4F(srcImage.clamp(ipart[0] + 3, ipart[1] + 1))); - - Vec4F c = cubic4(fpart[0], - Vec4F(srcImage.clamp(ipart[0], ipart[1] + 2)), - Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1] + 2)), - Vec4F(srcImage.clamp(ipart[0] + 2, ipart[1] + 2)), - Vec4F(srcImage.clamp(ipart[0] + 3, ipart[1] + 2))); - - Vec4F d = cubic4(fpart[0], - Vec4F(srcImage.clamp(ipart[0], ipart[1] + 3)), - Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1] + 3)), - Vec4F(srcImage.clamp(ipart[0] + 2, ipart[1] + 3)), - Vec4F(srcImage.clamp(ipart[0] + 3, ipart[1] + 3))); - - auto result = cubic4(fpart[1], a, b, c, d); - - destImage.set({x, y}, Vec4B( - clamp(result[0], 0.0f, 255.0f), - clamp(result[1], 0.0f, 255.0f), - clamp(result[2], 0.0f, 255.0f), - clamp(result[3], 0.0f, 255.0f) - )); - } - } - - return destImage; -} -#pragma GCC pop_options - StringList colorDirectivesFromConfig(JsonArray const& directives) { List result; diff --git a/source/core/StarImageProcessing.hpp b/source/core/StarImageProcessing.hpp index 8316d18..dfc9420 100644 --- a/source/core/StarImageProcessing.hpp +++ b/source/core/StarImageProcessing.hpp @@ -10,10 +10,6 @@ STAR_CLASS(Image); STAR_EXCEPTION(ImageOperationException, StarException); -Image scaleNearest(Image const& srcImage, Vec2F const& scale); -Image scaleBilinear(Image const& srcImage, Vec2F const& scale); -Image scaleBicubic(Image const& srcImage, Vec2F const& scale); - StringList colorDirectivesFromConfig(JsonArray const& directives); String paletteSwapDirectivesFromConfig(Json const& swaps); diff --git a/source/core/StarImageScaling.cpp b/source/core/StarImageScaling.cpp new file mode 100644 index 0000000..96837aa --- /dev/null +++ b/source/core/StarImageScaling.cpp @@ -0,0 +1,98 @@ +#include "StarImage.hpp" +#include "StarImageScaling.hpp" +#include "StarInterpolation.hpp" + +namespace Star { + +Image scaleNearest(Image const& srcImage, Vec2F const& scale) { + Vec2U srcSize = srcImage.size(); + Vec2U destSize = Vec2U::round(vmult(Vec2F(srcSize), scale)); + destSize[0] = max(destSize[0], 1u); + destSize[1] = max(destSize[1], 1u); + + Image destImage(destSize, srcImage.pixelFormat()); + + for (unsigned y = 0; y < destSize[1]; ++y) { + for (unsigned x = 0; x < destSize[0]; ++x) + destImage.set({x, y}, srcImage.clamp(Vec2I::round(vdiv(Vec2F(x, y), scale)))); + } + return destImage; +} + +Image scaleBilinear(Image const& srcImage, Vec2F const& scale) { + Vec2U srcSize = srcImage.size(); + Vec2U destSize = Vec2U::round(vmult(Vec2F(srcSize), scale)); + destSize[0] = max(destSize[0], 1u); + destSize[1] = max(destSize[1], 1u); + + Image destImage(destSize, srcImage.pixelFormat()); + + for (unsigned y = 0; y < destSize[1]; ++y) { + for (unsigned x = 0; x < destSize[0]; ++x) { + auto pos = vdiv(Vec2F(x, y), scale); + auto ipart = Vec2I::floor(pos); + auto fpart = pos - Vec2F(ipart); + + auto result = lerp(fpart[1], lerp(fpart[0], Vec4F(srcImage.clamp(ipart[0], ipart[1])), Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1]))), lerp(fpart[0], + Vec4F(srcImage.clamp(ipart[0], ipart[1] + 1)), Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1] + 1)))); + + destImage.set({x, y}, Vec4B(result)); + } + } + + return destImage; +} + +Image scaleBicubic(Image const& srcImage, Vec2F const& scale) { + Vec2U srcSize = srcImage.size(); + Vec2U destSize = Vec2U::round(vmult(Vec2F(srcSize), scale)); + destSize[0] = max(destSize[0], 1u); + destSize[1] = max(destSize[1], 1u); + + Image destImage(destSize, srcImage.pixelFormat()); + + for (unsigned y = 0; y < destSize[1]; ++y) { + for (unsigned x = 0; x < destSize[0]; ++x) { + auto pos = vdiv(Vec2F(x, y), scale); + auto ipart = Vec2I::floor(pos); + auto fpart = pos - Vec2F(ipart); + + Vec4F a = cubic4(fpart[0], + Vec4F(srcImage.clamp(ipart[0], ipart[1])), + Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1])), + Vec4F(srcImage.clamp(ipart[0] + 2, ipart[1])), + Vec4F(srcImage.clamp(ipart[0] + 3, ipart[1]))); + + Vec4F b = cubic4(fpart[0], + Vec4F(srcImage.clamp(ipart[0], ipart[1] + 1)), + Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1] + 1)), + Vec4F(srcImage.clamp(ipart[0] + 2, ipart[1] + 1)), + Vec4F(srcImage.clamp(ipart[0] + 3, ipart[1] + 1))); + + Vec4F c = cubic4(fpart[0], + Vec4F(srcImage.clamp(ipart[0], ipart[1] + 2)), + Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1] + 2)), + Vec4F(srcImage.clamp(ipart[0] + 2, ipart[1] + 2)), + Vec4F(srcImage.clamp(ipart[0] + 3, ipart[1] + 2))); + + Vec4F d = cubic4(fpart[0], + Vec4F(srcImage.clamp(ipart[0], ipart[1] + 3)), + Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1] + 3)), + Vec4F(srcImage.clamp(ipart[0] + 2, ipart[1] + 3)), + Vec4F(srcImage.clamp(ipart[0] + 3, ipart[1] + 3))); + + auto result = cubic4(fpart[1], a, b, c, d); + + destImage.set({x, y}, Vec4B( + clamp(result[0], 0.0f, 255.0f), + clamp(result[1], 0.0f, 255.0f), + clamp(result[2], 0.0f, 255.0f), + clamp(result[3], 0.0f, 255.0f) + )); + } + } + + return destImage; +} + +} \ No newline at end of file diff --git a/source/core/StarImageScaling.hpp b/source/core/StarImageScaling.hpp new file mode 100644 index 0000000..6a7271b --- /dev/null +++ b/source/core/StarImageScaling.hpp @@ -0,0 +1,8 @@ +namespace Star { + +STAR_CLASS(Image); +Image scaleNearest(Image const& srcImage, Vec2F const& scale); +Image scaleBilinear(Image const& srcImage, Vec2F const& scale); +Image scaleBicubic(Image const& srcImage, Vec2F const& scale); + +} \ No newline at end of file From 75ff3cbba9b44a357af0e24ec99a0c28fcdf8d43 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sat, 28 Dec 2024 13:42:00 +1100 Subject: [PATCH 129/181] Update CMakeLists.txt --- source/core/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/CMakeLists.txt b/source/core/CMakeLists.txt index 6deb473..16cf576 100644 --- a/source/core/CMakeLists.txt +++ b/source/core/CMakeLists.txt @@ -232,7 +232,7 @@ IF(STAR_PRECOMPILED_HEADERS) ENDIF() IF(STAR_COMPILER STREQUAL "gnu") - SET_SOURCE_FILES_PROPERTIES(StarImageScaling.cpp PROPERTIES COMPILE_FLAGS "-O2") + SET_SOURCE_FILES_PROPERTIES(StarImageScaling.cpp PROPERTIES COMPILE_FLAGS "-O2 -fno-trapping-math -fno-unsafe-math-optimizations") ENDIF() IF(STAR_USE_JEMALLOC AND JEMALLOC_IS_PREFIXED) From d2e1826865d745dbf8eb7670b49d5c88d4ecc297 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Sat, 28 Dec 2024 19:58:06 -0800 Subject: [PATCH 130/181] Update universeclient.lua --- assets/opensb/scripts/opensb/universeclient/universeclient.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/opensb/scripts/opensb/universeclient/universeclient.lua b/assets/opensb/scripts/opensb/universeclient/universeclient.lua index cad342b..a534c25 100644 --- a/assets/opensb/scripts/opensb/universeclient/universeclient.lua +++ b/assets/opensb/scripts/opensb/universeclient/universeclient.lua @@ -1,2 +1,2 @@ require "/scripts/opensb/util/modules.lua" -modules("/scripts/opensb/universeclient/", {"voicemanager"}) \ No newline at end of file +modules("/scripts/opensb/universeclient/", {"voicemanager","loadconfig"}) From d63501aa07821ba79ae0b0ebf9e9f53b714a25c8 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Sat, 28 Dec 2024 19:58:18 -0800 Subject: [PATCH 131/181] Add files via upload --- .../opensb/universeclient/loadconfig.lua | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 assets/opensb/scripts/opensb/universeclient/loadconfig.lua diff --git a/assets/opensb/scripts/opensb/universeclient/loadconfig.lua b/assets/opensb/scripts/opensb/universeclient/loadconfig.lua new file mode 100644 index 0000000..2bb3ef8 --- /dev/null +++ b/assets/opensb/scripts/opensb/universeclient/loadconfig.lua @@ -0,0 +1,22 @@ +-- Meant to manage loading various miscellaneous things from configuration, such as shader parameters. + +local module = {} +modules.config_loader = module + +function module.init() + local shaderConfig = root.getConfiguration("postProcessGroups") or {} + local postProcessGroups = renderer.postProcessGroups() + local changes = false + for k,v in next, shaderConfig do + local group = postProcessGroups[k] + if v.parameters then + for k2,v2 in next, group.parameters do + if v.parameters[k2] ~= nil then + for _,e in next, v2.effects do + renderer.setEffectParameter(e,k2,v.parameters[k2]) + end + end + end + end + end +end From e33d260e6d30a8b6d08c174fd9b315b9a10d6490 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Sat, 28 Dec 2024 20:02:00 -0800 Subject: [PATCH 132/181] Add files via upload --- .../opensb/interface/opensb/shaders/select.png | Bin 0 -> 4583 bytes .../interface/opensb/shaders/selectend.png | Bin 0 -> 4094 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/opensb/interface/opensb/shaders/select.png create mode 100644 assets/opensb/interface/opensb/shaders/selectend.png diff --git a/assets/opensb/interface/opensb/shaders/select.png b/assets/opensb/interface/opensb/shaders/select.png new file mode 100644 index 0000000000000000000000000000000000000000..dc649b4e39a5fce11b972ded4b4f4c74f1b0d3da GIT binary patch literal 4583 zcmeHKd2ka|7~cxm8d?uPKn`8D9w2V^=x&l-leUl)8rwi9Efy8w?e5!lZITViwn-Uh zaN2@{!oc8o6hR%-swg1iP(?YEQ~$7D+=Cnnq6i}5bVd&K?WU(X<8%c7YG#t%_ulvY z-uL~!-?uNjAUJ7amTi~~!>}xWp|1p8Ys~wMzUX&vQOR@YvTaUjxlsZVcr>P~S_tAs zZ4}}#si_#2JQxl>IA9x|ap~kBPn~;Za>Q5r8xOyVRqm58uNEG4@*8RO>-9b3NQ%iDKI1H4O1HugE|qnhgR zWLAr6z!|zKf8QO(UgbguZqLL-xc)RyLo?O*#>aO@OS(CQFsY&ewll6`{ZxF z9=#~@`5AeErelknHZ%>a7;>^{?V+6~8m78K6N(#`1ivWzbhoe*Oy2Vs|%!J_3SCT+p68*(*N{PIAtDC=Q6 zP;?2}li?^*1%|ovl2IU6K?9dyg%0@!E(1l4K;FZ9=3l zd@wG@w5Xx!5!}QCl3s0i2m-C+?eT@9fj|d*B;LjX;)6vWOa+pT(Q#W8VGXl!0l$;p1Wm?tO5bir_0r5cz&OUF!vV~UDg!Q zx>X@VJAsQKT@EKhax5p166>T%nr0jlFUu^H*e+21NZbGs8JbWC+^!)U1*$@h#4;p= zoScGiaf(9b2&y6j7cEE(>;f@4rXf{=P}itTCuL*XS0N|D70dMpf3IkhmTfK)V6VJ(=1i{pZR55d~$&Y55c7%Fn`5XD-gI@!5U zs)gZH1DI?w&K#cOIDvN1PDWsuPNQis7Dq}nF&WyPr5wf5hv z&E~<~sgf6JakPJ}HI?e9sc?2`lp2OKtCeuvY6=m^sTAU%1}avZ2rIQDSAs|dL{E=4 zxwg-1|0D$diZ)lU)1NGCv%Ng47A$vL4)3Jd@w3mk&v zU}=SCUEPEJ?ZPkk z4D`sjS6#hy^@xEU8TYE|iqU23d?|(z^j|iCUU@=i$1I=$5wru%OG?{Mr0|n{dXO8TfW`C+-$HQof@%zS=7VbK;m$?bUGPmY`zh?`4 zWaaP$^+&$(@vDyyJN^3Tw`YA+*RTKJd-kuLak}x_KCAEQGvZLcQI8^L%wI6cw`TmT Gx<3Jaqd!pq literal 0 HcmV?d00001 diff --git a/assets/opensb/interface/opensb/shaders/selectend.png b/assets/opensb/interface/opensb/shaders/selectend.png new file mode 100644 index 0000000000000000000000000000000000000000..99908d61a2e3fb1a2badb9b1c0e756fc24b4382e GIT binary patch literal 4094 zcmeHKYitx%6kbXrrBEbDERs^jDU?@c=drV|p$oLT+jg-F+jh}{5twH?ba!XjnRa&z zLdv5R6jMMW6beE}QP6?{8o+=;3ci5wh!QAZs60b7G!l6T_0DXcfy6YCf8Atv?mhQA z-#O>I=icnB@J!1|N*tc3)9I32xsC$x?4yno;=%8c%RfiK~_+ z(I5};5mC_TA{YD~|DdB#!sAop%H!krMp6zQ;LPXmR%flfuxi=y<7w05AKrMpFDdHp18*ve`;~&ZqB?jA%FB= z_tG7y5g*x76hAKkx313m_`%n^y_Xv1oS)cG{|7cjdF#>k%Xcbrz6!7VL}o}%e@ORY z@^3=?D?@fBr8n$JtBSs#KKc8@6YE}>17**g8ah;Y02Bv{cDu)Ax3?DqO4wLe^TpJo zo}pET_ilwxJLeBxKCofLiQnhWNXS|~Y(i1pnQe{C5c`^fg?+C$M%FKd?hibfc=Cyv zvaD+yP~F-bJlT3>!Io>I@@MH&rqs?@o~-oyXz7IFTS*&6T=G6ZP^-EI_J*G9ZkDeuDZA=IBL=0iSuh4ua3DJ*m$h!M4%@9 z?9Jn6n~tUO$v5hET{zaftZ-pURo?m<&*{~|?Ud#($J`s6uz&lgHRGk={b|4{vKBqw889&wgatY5x2~H1%cr(!8Csn(=QYAGxjj zWix&4z^kPX{=PU|XsWorS^6igX`g5I$Y9!H&;}6^Y<-bCk76aip5`Qm*GK$8&=Wdc z#^gwlW=nYmV)$Y)V1xfWco>F6&IZ3>bYt$Ioi7n{D?)r>#WXKlQOa65c=Dvgj0gn? z{JcU#5x*}WQxO}i@ls%{no$_iAWEqXE^>PyyAlo8?ts=$%m zMge9vxI|Hc6pDt!VSU)3mqNuTZnaubj6ewj0SH8n1{6Ai1mrZ8BF5q1Wi})R6;TR6 zDksfIWr_`k!8+8QpFik!chCpqHWh##XoL=;xE@3OezdEHtT@X7Nn1kC^pL&a1fd1I zER}^=-dWBEl(eoC9NXa^EDQOxayS;{eY_t)We^qb7Ba`>_H=lt5)_O6pyma{?uJxE zp;N4Gxv48!Ib9P0?j5|{(CxKrV1RPFDTl8 z86jE1idc9OLky&aHPEb)r3I!7l`9}Cbb#emDnPCm0T0fa%@{`D2ySJp2+5E%LbE0T zp)Cvn>;}PXv38-D9uh%U(!Q=)sZ<=GG7)Bjkr9jtV-`q+G#D|&$}%c5XEibmW-$<$ zM#ZsIwiNQyU^_)WUCg7wK(V%<3QlEuTsD}{$Do?Uw^BGs8BGXgp|CD^i4%qBf1%aG17*av zJXe%K{HSJ%ov1>7ery(-`b6z0L6CMRD4LCxAk*bMr{xK_VoPiZ9Vq6(?a|h*?RN1Q ztzaey+$fkV2u@fC1T>Zzu?n04!D$o8S~wmzl7{Z=vLq;BI>cud108`@pglFMpt0IU zjq8pMm+Ub%YZ>X8CH0{3=TuUtJ+phw`|?)u;4O6+`{;sfAcP#C-{eY+=9 z0WVr{%xgIgoo>gfGy=@}2Xkl2I^BSm)NdbM?Z#oi*iUh}o&9bO9MN}> Date: Sat, 28 Dec 2024 20:02:37 -0800 Subject: [PATCH 133/181] Update shaders.config --- assets/opensb/interface/opensb/shaders/shaders.config | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/assets/opensb/interface/opensb/shaders/shaders.config b/assets/opensb/interface/opensb/shaders/shaders.config index 5154831..864574e 100644 --- a/assets/opensb/interface/opensb/shaders/shaders.config +++ b/assets/opensb/interface/opensb/shaders/shaders.config @@ -3,7 +3,10 @@ "scriptDelta" : 0, "scriptWidgetCallbacks" : [ "selectGroup", - "toggleGroupEnabled" + "toggleGroupEnabled", + "sliderOptionModified", + "textboxOptionModified", + "selectOptionPressed" ], "gui" : { From ebabc7bf8e872b7659bb189c1e45b31dfd2f48ab Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Sat, 28 Dec 2024 20:02:52 -0800 Subject: [PATCH 134/181] Update shaders.lua --- .../interface/opensb/shaders/shaders.lua | 152 +++++++++++++++++- 1 file changed, 147 insertions(+), 5 deletions(-) diff --git a/assets/opensb/interface/opensb/shaders/shaders.lua b/assets/opensb/interface/opensb/shaders/shaders.lua index 0030b5c..0c2d19c 100644 --- a/assets/opensb/interface/opensb/shaders/shaders.lua +++ b/assets/opensb/interface/opensb/shaders/shaders.lua @@ -17,6 +17,14 @@ local groups = {} local widgetsToGroups = {} local allSettings = {} +local shaderConfig + +function displayed() + shaderConfig = root.getConfiguration("postProcessGroups") +end +function dismissed() + shaderConfig = nil +end local function addGroupToList(data) local name = widget.addListItem(GROUP_LIST_WIDGET) @@ -67,7 +75,7 @@ local function addOptionGroup(data, i, added) added[#added + 1] = name local label = { type = "label", - value = data.name, + value = data.label, wrapWidth = 120, fontSize = 8, hAnchor = "mid", @@ -77,6 +85,16 @@ local function addOptionGroup(data, i, added) widget.addChild(fmt("%s.%s", BINDS_WIDGET, name), label, "text") end +local function digitRegex(n) + local i = 0 + while n ~= math.floor(n) do + n = n * 10 + i = i + 1 + end + return fmt("%%.%df",i) -- create format string %.nf, where n = %d (i with no decimal points) +end +local optionPrefix = "option_" +local optionOffset = #optionPrefix+1 local function addOption(data, i, added) local y = (i - 1) * -14 local bg = { @@ -84,12 +102,12 @@ local function addOption(data, i, added) file = PATH .. "optionname.png", position = {-12, y} } - local name = "label_" .. i + local name = "label_" .. data.name widget.addChild(OPTIONS_WIDGET, bg, name) added[#added + 1] = name local label = { type = "label", - value = data.name, + value = data.label, wrapWidth = 120, fontSize = 8, hAnchor = "mid", @@ -97,7 +115,115 @@ local function addOption(data, i, added) position = {62, 6} } widget.addChild(fmt("%s.%s", OPTIONS_WIDGET, name), label, "text") + local value = data.default or 0 + if not shaderConfig[activeGroup] then + shaderConfig[activeGroup] = {parameters={}} + end + if not shaderConfig[activeGroup].parameters then + shaderConfig[activeGroup].parameters = {} + end + if shaderConfig[activeGroup].parameters[data.name] ~= nil then + value = shaderConfig[activeGroup].parameters[data.name] + end + -- todo: finish this + if data.type == "slider" then + local range = data.range or {0,1} + local delta = data.delta or 0.01 + -- for some reason ranges require ints so + local r = {range[1]/delta, range[2]/delta, 1} + + local slider = { + type = "slider", + callback = "sliderOptionModified", + position = {110, y + 2}, + gridImage = "/interface/optionsmenu/smallselection.png", + range = r + } + name = optionPrefix..data.name + added[#added + 1] = name + widget.addChild(OPTIONS_WIDGET, slider, name) + + widget.setSliderValue(fmt("%s.%s",OPTIONS_WIDGET,name), value/delta) + local valLabel = { + type = "label", + value = fmt(digitRegex(delta),value), + position = {186, y + 2} + } + added[#added + 1] = name.."_value" + widget.addChild(OPTIONS_WIDGET, valLabel, name.."_value") + elseif data.type == "select" then + local n = #data.values + local width = math.floor(118/n) + local by = y + local buttons = {} + for i=0,n-1 do + local img = fmt("%sselect.png?crop=0;0;%.0f;13",PATH,width) + local button = { + type = "button", + callback="selectOptionPressed", + caption = data.values[i+1], + base = img, + hover = img.."?brightness=-25", + baseImageChecked = img.."?multiply=00ff00", + hoverImageChecked = img.."?multiply=00ff00?brightness=-25", + position = {110+width*i, by}, + pressedOffset = {0, 0}, + checkable = true, + checked = (value == i) + } + name = "select_"..data.name.."_"..i + added[#added + 1] = name + widget.addChild(OPTIONS_WIDGET, button, name) + table.insert(buttons,{widget=fmt("%s.%s",OPTIONS_WIDGET,name),index=i}) + end + for k,v in next, buttons do + widget.setData(v.widget,{option=data,index=v.index,buttons=buttons}) + end + --[[local bge = { + type = "image", + file = PATH.."selectend.png", + position = {110+width*3, by} + } + name = "bgend_"..data.name + added[#added + 1] = name + widget.addChild(OPTIONS_WIDGET, bge, name)]] + end +end + +function sliderOptionModified(option, odata) + local oname = string.sub(option, optionOffset) + local parameter = groups[activeGroup].parameters[oname] + local value = widget.getSliderValue(fmt("%s.%s",OPTIONS_WIDGET,option))*parameter.delta + + widget.setText(fmt("%s.%s",OPTIONS_WIDGET,option.."_value"), fmt(digitRegex(parameter.delta),value)) + + for k,v in next, parameter.effects do + renderer.setEffectParameter(v, oname, value) + end + shaderConfig[activeGroup].parameters[oname] = value + root.setConfiguration("postProcessGroups",shaderConfig) +end + +function selectOptionPressed(button,bdata) + sb.logInfo(sb.print(bdata)) + + for k,v in next, bdata.buttons do + if v.index ~= bdata.index then + widget.setChecked(v.widget, false) + end + end + + value = bdata.index + + local oname = bdata.option.name + local parameter = groups[activeGroup].parameters[oname] + + for k,v in next, parameter.effects do + renderer.setEffectParameter(v, oname, value) + end + shaderConfig[activeGroup].parameters[oname] = value + root.setConfiguration("postProcessGroups",shaderConfig) end local function addEnabled(groupname, i, added) @@ -139,6 +265,7 @@ end function toggleGroupEnabled(checkbox, cdata) renderer.setPostProcessGroupEnabled(activeGroup, widget.getChecked(fmt("%s.%s",OPTIONS_WIDGET,checkbox)), true) + shaderConfig = root.getConfiguration("postProcessGroups") end function selectGroup() @@ -163,7 +290,21 @@ function selectGroup() local added = {} local index = 0 addEnabled(group.groupId,index,added) - + if group.categories then + + elseif group.parameters then + local sortedParams = {} + for k,v in next, group.parameters do + v.name = k + sortedParams[#sortedParams+1] = v + end + table.sort(sortedParams, alphabeticalNameSortLesser) + + for k,v in next, sortedParams do + index = index + 1 + addOption(v, index, added) + end + end --[[ local categories = group.categories or {} if not categories.unsorted then @@ -198,7 +339,8 @@ function selectGroup() addOption(category.sortedOptions[iB], index, added) end end - end]] + end + ]] widget.setData(OPTIONS_WIDGET, added) end From 740cf89122b1010da4db21fb404f483c2f7a019f Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Sat, 28 Dec 2024 20:04:19 -0800 Subject: [PATCH 135/181] Update StarRenderer_opengl.hpp --- source/application/StarRenderer_opengl.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/application/StarRenderer_opengl.hpp b/source/application/StarRenderer_opengl.hpp index 36b8354..79e5400 100644 --- a/source/application/StarRenderer_opengl.hpp +++ b/source/application/StarRenderer_opengl.hpp @@ -25,6 +25,9 @@ public: void loadEffectConfig(String const& name, Json const& effectConfig, StringMap const& shaders) override; void setEffectParameter(String const& parameterName, RenderEffectParameter const& parameter) override; + void setEffectScriptableParameter(String const& effectName, String const& parameterName, RenderEffectParameter const& parameter) override; + Maybe getEffectScriptableParameter(String const& effectName, String const& parameterName) override; + Maybe getEffectScriptableParameterType(String const& effectName, String const& parameterName) override; void setEffectTexture(String const& textureName, ImageView const& image) override; void setScissorRect(Maybe const& scissorRect) override; @@ -191,6 +194,7 @@ private: GLuint program = 0; Json config; StringMap parameters; + StringMap scriptables; // scriptable parameters which can be changed when the effect is not loaded StringMap textures; StringMap attributes; From 5e072417414a0d9a51d7c0c574fd0cdfc1fa29c9 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Sat, 28 Dec 2024 20:04:59 -0800 Subject: [PATCH 136/181] Update StarRenderer.hpp --- source/application/StarRenderer.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/application/StarRenderer.hpp b/source/application/StarRenderer.hpp index 2a156f7..2b106ff 100644 --- a/source/application/StarRenderer.hpp +++ b/source/application/StarRenderer.hpp @@ -120,7 +120,7 @@ public: virtual void set(List& primitives) = 0; }; -typedef Variant RenderEffectParameter; +typedef Variant RenderEffectParameter; class Renderer { public: @@ -141,6 +141,9 @@ public: // The effect config will specify named parameters and textures which can be // set here. virtual void setEffectParameter(String const& parameterName, RenderEffectParameter const& parameter) = 0; + virtual void setEffectScriptableParameter(String const& effectName, String const& parameterName, RenderEffectParameter const& parameter) = 0; + virtual Maybe getEffectScriptableParameter(String const& effectName, String const& parameterName) = 0; + virtual Maybe getEffectScriptableParameterType(String const& effectName, String const& parameterName) = 0; virtual void setEffectTexture(String const& textureName, ImageView const& image) = 0; virtual bool switchEffectConfig(String const& name) = 0; From 1a0bf768f071d26a04ac20c5f0eb43056b14cc8f Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Sat, 28 Dec 2024 20:07:04 -0800 Subject: [PATCH 137/181] Update StarRenderer_opengl.cpp --- source/application/StarRenderer_opengl.cpp | 112 ++++++++++++++++++--- 1 file changed, 97 insertions(+), 15 deletions(-) diff --git a/source/application/StarRenderer_opengl.cpp b/source/application/StarRenderer_opengl.cpp index 9d0d717..ceb945d 100644 --- a/source/application/StarRenderer_opengl.cpp +++ b/source/application/StarRenderer_opengl.cpp @@ -308,21 +308,39 @@ void OpenGlRenderer::loadEffectConfig(String const& name, Json const& effectConf throw RendererException::format("Unrecognized effect parameter type '{}'", type); } - effect.parameters[p.first] = effectParameter; - - if (Json def = p.second.get("default", {})) { - if (type == "bool") { - setEffectParameter(p.first, def.toBool()); - } else if (type == "int") { - setEffectParameter(p.first, (int)def.toInt()); - } else if (type == "float") { - setEffectParameter(p.first, def.toFloat()); - } else if (type == "vec2") { - setEffectParameter(p.first, jsonToVec2F(def)); - } else if (type == "vec3") { - setEffectParameter(p.first, jsonToVec3F(def)); - } else if (type == "vec4") { - setEffectParameter(p.first, jsonToVec4F(def)); + if (p.second.getBool("scriptable",false)) { + if (Json def = p.second.get("default", {})) { + if (type == "bool") { + effectParameter.parameterValue = (RenderEffectParameter)def.toBool(); + } else if (type == "int") { + effectParameter.parameterValue = (RenderEffectParameter)(int)def.toInt(); + } else if (type == "float") { + effectParameter.parameterValue = (RenderEffectParameter)def.toFloat(); + } else if (type == "vec2") { + effectParameter.parameterValue = (RenderEffectParameter)jsonToVec2F(def); + } else if (type == "vec3") { + effectParameter.parameterValue = (RenderEffectParameter)jsonToVec3F(def); + } else if (type == "vec4") { + effectParameter.parameterValue = (RenderEffectParameter)jsonToVec4F(def); + } + } + effect.scriptables[p.first] = effectParameter; + } else { + effect.parameters[p.first] = effectParameter; + if (Json def = p.second.get("default", {})) { + if (type == "bool") { + setEffectParameter(p.first, def.toBool()); + } else if (type == "int") { + setEffectParameter(p.first, (int)def.toInt()); + } else if (type == "float") { + setEffectParameter(p.first, def.toFloat()); + } else if (type == "vec2") { + setEffectParameter(p.first, jsonToVec2F(def)); + } else if (type == "vec3") { + setEffectParameter(p.first, jsonToVec3F(def)); + } else if (type == "vec4") { + setEffectParameter(p.first, jsonToVec4F(def)); + } } } } @@ -384,6 +402,50 @@ void OpenGlRenderer::setEffectParameter(String const& parameterName, RenderEffec ptr->parameterValue = value; } +void OpenGlRenderer::setEffectScriptableParameter(String const& effectName, String const& parameterName, RenderEffectParameter const& value) { + auto find = m_effects.find(effectName); + if (find == m_effects.end()) + return; + + Effect& effect = find->second; + + auto ptr = effect.scriptables.ptr(parameterName); + if (!ptr || (ptr->parameterValue && *ptr->parameterValue == value)) + return; + + if (ptr->parameterType != value.typeIndex()) + throw RendererException::format("OpenGlRenderer::setEffectScriptableParameter '{}' parameter type mismatch", parameterName); + + ptr->parameterValue = value; +} + +Maybe OpenGlRenderer::getEffectScriptableParameter(String const& effectName, String const& parameterName) { + auto find = m_effects.find(effectName); + if (find == m_effects.end()) + return {}; + + Effect& effect = find->second; + + auto ptr = effect.scriptables.ptr(parameterName); + if (!ptr) + return {}; + + return ptr->parameterValue; +} +Maybe OpenGlRenderer::getEffectScriptableParameterType(String const& effectName, String const& parameterName) { + auto find = m_effects.find(effectName); + if (find == m_effects.end()) + return {}; + + Effect& effect = find->second; + + auto ptr = effect.scriptables.ptr(parameterName); + if (!ptr) + return {}; + + return ptr->parameterType; +} + void OpenGlRenderer::setEffectTexture(String const& textureName, ImageView const& image) { auto ptr = m_currentEffect->textures.ptr(textureName); if (!ptr) @@ -1063,6 +1125,26 @@ void OpenGlRenderer::setupGlUniforms(Effect& effect, Vec2U screenSize) { } glUniform2f(m_screenSizeUniform, screenSize[0], screenSize[1]); + + for (auto& param : effect.scriptables) { + auto ptr = ¶m.second; + auto mvalue = ptr->parameterValue; + if (mvalue) { + RenderEffectParameter value = mvalue.value(); + if (auto v = value.ptr()) + glUniform1i(ptr->parameterUniform, *v); + else if (auto v = value.ptr()) + glUniform1i(ptr->parameterUniform, *v); + else if (auto v = value.ptr()) + glUniform1f(ptr->parameterUniform, *v); + else if (auto v = value.ptr()) + glUniform2f(ptr->parameterUniform, (*v)[0], (*v)[1]); + else if (auto v = value.ptr()) + glUniform3f(ptr->parameterUniform, (*v)[0], (*v)[1], (*v)[2]); + else if (auto v = value.ptr()) + glUniform4f(ptr->parameterUniform, (*v)[0], (*v)[1], (*v)[2], (*v)[3]); + } + } } RefPtr OpenGlRenderer::getGlFrameBuffer(String const& id) { From f7dc97965dd245a1d9272bdb48d1f16dc0b82233 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Sat, 28 Dec 2024 20:07:34 -0800 Subject: [PATCH 138/181] Update StarRenderingLuaBindings.cpp --- source/client/StarRenderingLuaBindings.cpp | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/source/client/StarRenderingLuaBindings.cpp b/source/client/StarRenderingLuaBindings.cpp index 4c9e7a2..39dc1a1 100644 --- a/source/client/StarRenderingLuaBindings.cpp +++ b/source/client/StarRenderingLuaBindings.cpp @@ -1,6 +1,8 @@ #include "StarRenderingLuaBindings.hpp" +#include "StarJsonExtra.hpp" #include "StarLuaConverters.hpp" #include "StarClientApplication.hpp" +#include "StarRenderer.hpp" namespace Star { @@ -11,8 +13,30 @@ LuaCallbacks LuaBindings::makeRenderingCallbacks(ClientApplication* app) { callbacks.registerCallbackWithSignature>("setPostProcessGroupEnabled", bind(mem_fn(&ClientApplication::setPostProcessGroupEnabled), app, _1, _2, _3)); callbacks.registerCallbackWithSignature("postProcessGroupEnabled", bind(mem_fn(&ClientApplication::postProcessGroupEnabled), app, _1)); + // not entirely necessary (root.assetJson can achieve the same purpose) but may as well callbacks.registerCallbackWithSignature("postProcessGroups", bind(mem_fn(&ClientApplication::postProcessGroups), app)); + + // typedef Variant RenderEffectParameter; + // feel free to change this if there's a better way to do this + // specifically checks if the effect parameter is an int since Lua prefers converting the values to floats + callbacks.registerCallback("setEffectParameter", [app](String const& effectName, String const& effectParameter, RenderEffectParameter const& value) { + auto renderer = app->renderer(); + auto mtype = renderer->getEffectScriptableParameterType(effectName, effectParameter); + if (mtype) { + auto type = mtype.value(); + if (type == 1 && value.is()) { + renderer->setEffectScriptableParameter(effectName, effectParameter, (int)value.get()); + } else { + renderer->setEffectScriptableParameter(effectName, effectParameter, value); + } + } + }); + + callbacks.registerCallback("getEffectParameter", [app](String const& effectName, String const& effectParameter) { + auto renderer = app->renderer(); + return renderer->getEffectScriptableParameter(effectName, effectParameter); + }); return callbacks; } From 922427e25f0e6edf00909f8c6ae1dfc6770c7308 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Sat, 28 Dec 2024 20:08:17 -0800 Subject: [PATCH 139/181] Update StarScrollArea.cpp --- source/windowing/StarScrollArea.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/windowing/StarScrollArea.cpp b/source/windowing/StarScrollArea.cpp index f4cc140..775462a 100644 --- a/source/windowing/StarScrollArea.cpp +++ b/source/windowing/StarScrollArea.cpp @@ -384,7 +384,8 @@ bool ScrollArea::sendEvent(InputEvent const& event) { return true; } -void ScrollArea::update(float) { +void ScrollArea::update(float dt) { + Widget::update(dt); if (!m_visible) return; From ec6c8f0c3c72cd7a9c9ea97721f12225cff42406 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Sat, 28 Dec 2024 20:09:29 -0800 Subject: [PATCH 140/181] Update StarLuaConverters.hpp --- source/core/StarLuaConverters.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/core/StarLuaConverters.hpp b/source/core/StarLuaConverters.hpp index d9dfc67..c79cbdc 100644 --- a/source/core/StarLuaConverters.hpp +++ b/source/core/StarLuaConverters.hpp @@ -168,11 +168,11 @@ struct LuaConverter> { template struct LuaConverter> { static LuaValue from(LuaEngine& engine, Variant const& variant) { - return variant.call([&engine](auto const& a) { return luaFrom(engine, a); }); + return variant.call([&engine](auto const& a) { return engine.luaFrom(a); }); } static LuaValue from(LuaEngine& engine, Variant&& variant) { - return variant.call([&engine](auto& a) { return luaFrom(engine, std::move(a)); }); + return variant.call([&engine](auto& a) { return engine.luaFrom(std::move(a)); }); } static Maybe> to(LuaEngine& engine, LuaValue const& v) { @@ -217,7 +217,7 @@ struct LuaConverter> { static LuaValue from(LuaEngine& engine, MVariant const& variant) { LuaValue value; variant.call([&value, &engine](auto const& a) { - value = luaFrom(engine, a); + value = engine.luaFrom(a); }); return value; } @@ -225,7 +225,7 @@ struct LuaConverter> { static LuaValue from(LuaEngine& engine, MVariant&& variant) { LuaValue value; variant.call([&value, &engine](auto& a) { - value = luaFrom(engine, std::move(a)); + value = engine.luaFrom(std::move(a)); }); return value; } From 54b8f83b8507b56e0a4ecbb5a666c928c6ded1a9 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Sat, 28 Dec 2024 21:23:16 -0800 Subject: [PATCH 141/181] Documentation for renderer --- doc/lua/openstarbound.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/doc/lua/openstarbound.md b/doc/lua/openstarbound.md index 4d948bf..f4eff06 100644 --- a/doc/lua/openstarbound.md +++ b/doc/lua/openstarbound.md @@ -564,3 +564,42 @@ teleportOut
    #### `List` player.teamMembers() Returns an array, each entry being a table with `name`, `uuid`, `entity`, `healthPercentage` and `energyPercentage` + +--- + +# Renderer + +The new renderer table is accessible from almost every clientside script and allows configuring shaders. + +--- + +#### `void` renderer.setPostProcessGroupEnabled(String group, bool enabled, [bool save]) + +Enables or disables a post process shader group. If save is true, this change is saved to configuration as well. + +--- + +#### `bool` renderer.postProcessGroupEnabled(String group) + +Returns true if the specified post process group is enabled. + +--- + +#### `Json` renderer.postProcessGroups() + +Returns every post process group. Identical to grabbing them from client.config with root.assetJson. + +--- + +#### `Json` renderer.setEffectParameter(String effectName, String parameterName, RenderEffectParameter value) + +Sets the specified scriptable parameter of the specified shader effect to the provided value. +This is accessed from the shader as a uniform and must be defined in the effect's configuration. + +--- + +#### `RenderEffectParameter` renderer.getEffectParameter(String effectName, String parameterName) + +Returns the specified scriptable parameter of the specified shader effect. + +--- From 9beadf3e2c6f06f43259e48629598fe77c365797 Mon Sep 17 00:00:00 2001 From: Bottinator22 <59987380+Bottinator22@users.noreply.github.com> Date: Sun, 29 Dec 2024 12:23:26 -0800 Subject: [PATCH 142/181] oops since my hhcolour shader (which doesn't have any parameters) was the first one in the list, it didn't need to load any parameters, which hid a bug that caused errors if the first shader in the menu had parameters --- assets/opensb/interface/opensb/shaders/shaders.lua | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/assets/opensb/interface/opensb/shaders/shaders.lua b/assets/opensb/interface/opensb/shaders/shaders.lua index 0c2d19c..f9b6a32 100644 --- a/assets/opensb/interface/opensb/shaders/shaders.lua +++ b/assets/opensb/interface/opensb/shaders/shaders.lua @@ -19,13 +19,6 @@ local widgetsToGroups = {} local allSettings = {} local shaderConfig -function displayed() - shaderConfig = root.getConfiguration("postProcessGroups") -end -function dismissed() - shaderConfig = nil -end - local function addGroupToList(data) local name = widget.addListItem(GROUP_LIST_WIDGET) widget.setText(fmt("%s.%s.button", GROUP_LIST_WIDGET, name), data.friendlyName) @@ -351,6 +344,7 @@ local function initCallbacks() end function init() + shaderConfig = root.getConfiguration("postProcessGroups") --log = chat and chat.addMessage or sb.logInfo widget.clearListItems(GROUP_LIST_WIDGET) From 874ab3dd48a53c0cda6bb1faaeea27b52d2c1df2 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 14:49:51 +1100 Subject: [PATCH 143/181] ?saturation discrepancies: fixed mostly on GCC, 100% (seemingly?) on Clang --- .gitignore | 1 + source/CMakeLists.txt | 24 ++++++++++++------------ source/core/CMakeLists.txt | 4 ---- source/core/StarColor.cpp | 3 +++ source/core/StarImageScaling.cpp | 3 +-- source/core/StarImageScaling.hpp | 2 ++ 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index 4613197..eec550c 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ enc_temp_folder/ .cache/ /attic/user/ /attic/chucklefish/ +/attic/debug/ /tiled/ /assets/user/ /assets/devel/ diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 59fa0a6..ad3026b 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -285,14 +285,14 @@ if(STAR_COMPILER_GNU) set(CMAKE_C_FLAGS_DEBUG "-g -Og") set(CMAKE_CXX_FLAGS_DEBUG "-g -Og") - set(CMAKE_C_FLAGS_RELWITHASSERTS "-g -Ofast") - set(CMAKE_CXX_FLAGS_RELWITHASSERTS "-g -Ofast") + set(CMAKE_C_FLAGS_RELWITHASSERTS "-g -O3 -ffast-math") + set(CMAKE_CXX_FLAGS_RELWITHASSERTS "-g -O3 -ffast-math") - set(CMAKE_C_FLAGS_RELWITHDEBINFO "-g -DNDEBUG -Ofast") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -DNDEBUG -Ofast") + set(CMAKE_C_FLAGS_RELWITHDEBINFO "-g -DNDEBUG -O3 -ffast-math") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -DNDEBUG -O3 -ffast-math") - set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -Ofast") - set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -Ofast") + set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O3 -ffast-math") + set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -ffast-math") set(CMAKE_SKIP_BUILD_RPATH TRUE) @@ -316,14 +316,14 @@ elseif(STAR_COMPILER_CLANG) set(CMAKE_C_FLAGS_DEBUG "-g") set(CMAKE_CXX_FLAGS_DEBUG "-g") - set(CMAKE_C_FLAGS_RELWITHASSERTS "-g -Ofast") - set(CMAKE_CXX_FLAGS_RELWITHASSERTS "-g -Ofast") + set(CMAKE_C_FLAGS_RELWITHASSERTS "-g -O3 -ffast-math") + set(CMAKE_CXX_FLAGS_RELWITHASSERTS "-g -O3 -ffast-math") - set(CMAKE_C_FLAGS_RELWITHDEBINFO "-g -DNDEBUG -Ofast") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -DNDEBUG -Ofast") + set(CMAKE_C_FLAGS_RELWITHDEBINFO "-g -DNDEBUG -O3 -ffast-math") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -DNDEBUG -O3 -ffast-math") - set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -Ofast") - set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -Ofast") + set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O3 -ffast-math") + set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -ffast-math") set(CMAKE_SKIP_BUILD_RPATH TRUE) diff --git a/source/core/CMakeLists.txt b/source/core/CMakeLists.txt index 16cf576..3d00baf 100644 --- a/source/core/CMakeLists.txt +++ b/source/core/CMakeLists.txt @@ -231,10 +231,6 @@ IF(STAR_PRECOMPILED_HEADERS) TARGET_PRECOMPILE_HEADERS (star_core PUBLIC StarPch.hpp) ENDIF() -IF(STAR_COMPILER STREQUAL "gnu") - SET_SOURCE_FILES_PROPERTIES(StarImageScaling.cpp PROPERTIES COMPILE_FLAGS "-O2 -fno-trapping-math -fno-unsafe-math-optimizations") -ENDIF() - IF(STAR_USE_JEMALLOC AND JEMALLOC_IS_PREFIXED) SET_SOURCE_FILES_PROPERTIES(StarMemory.cpp PROPERTIES COMPILE_DEFINITIONS STAR_JEMALLOC_IS_PREFIXED diff --git a/source/core/StarColor.cpp b/source/core/StarColor.cpp index 7da8dd4..4eb726c 100644 --- a/source/core/StarColor.cpp +++ b/source/core/StarColor.cpp @@ -322,6 +322,8 @@ Vec3F Color::toRgbF() const { return Vec3F(redF(), greenF(), blueF()); } +#pragma GCC push_options +#pragma GCC optimize("-fno-fast-math") Vec4F Color::toHsva() const { float h, s, v; @@ -365,6 +367,7 @@ Vec4F Color::toHsva() const { return Vec4F(h, s, v, alphaF()); } +#pragma GCC pop_options String Color::toHex() const { auto rgba = toRgba(); diff --git a/source/core/StarImageScaling.cpp b/source/core/StarImageScaling.cpp index 96837aa..aa94359 100644 --- a/source/core/StarImageScaling.cpp +++ b/source/core/StarImageScaling.cpp @@ -33,8 +33,7 @@ Image scaleBilinear(Image const& srcImage, Vec2F const& scale) { auto ipart = Vec2I::floor(pos); auto fpart = pos - Vec2F(ipart); - auto result = lerp(fpart[1], lerp(fpart[0], Vec4F(srcImage.clamp(ipart[0], ipart[1])), Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1]))), lerp(fpart[0], - Vec4F(srcImage.clamp(ipart[0], ipart[1] + 1)), Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1] + 1)))); + auto result = lerp(fpart[1], lerp(fpart[0], Vec4F(srcImage.clamp(ipart[0], ipart[1])), Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1]))), lerp(fpart[0], Vec4F(srcImage.clamp(ipart[0], ipart[1] + 1)), Vec4F(srcImage.clamp(ipart[0] + 1, ipart[1] + 1)))); destImage.set({x, y}, Vec4B(result)); } diff --git a/source/core/StarImageScaling.hpp b/source/core/StarImageScaling.hpp index 6a7271b..d758169 100644 --- a/source/core/StarImageScaling.hpp +++ b/source/core/StarImageScaling.hpp @@ -1,3 +1,5 @@ +#pragma once + namespace Star { STAR_CLASS(Image); From 5b520556cf071223a5790d0d08ffadac9f0c07e0 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 14:50:10 +1100 Subject: [PATCH 144/181] switch Linux builds to Clang (this will surely end well!) --- source/CMakePresets.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/CMakePresets.json b/source/CMakePresets.json index a2c59e9..7efdc23 100644 --- a/source/CMakePresets.json +++ b/source/CMakePresets.json @@ -47,6 +47,8 @@ "binaryDir": "${sourceParentDir}/build/linux-release", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", + "CMAKE_C_COMPILER": "clang", + "CMAKE_CXX_COMPILER": "clang++", "VCPKG_TARGET_TRIPLET": "x64-linux-mixed", "CMAKE_INCLUDE_PATH": "${sourceParentDir}/lib/linux/include", "CMAKE_LIBRARY_PATH": "${sourceParentDir}/lib/linux", From 9e3341f2f25861b1a0c5dc62a97163ed4ab59254 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 14:59:15 +1100 Subject: [PATCH 145/181] Update StarMemory.cpp --- source/core/StarMemory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/StarMemory.cpp b/source/core/StarMemory.cpp index 6ecc509..dc13d08 100644 --- a/source/core/StarMemory.cpp +++ b/source/core/StarMemory.cpp @@ -51,7 +51,7 @@ namespace Star { void free(void* ptr, size_t size) { if (ptr) - ::sdallocx(ptr, size, 0); + je_sdallocx(ptr, size, 0); } #endif #elif STAR_USE_MIMALLOC From 4903d39eed1af80021e95424731038080ed1c9a3 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 15:26:01 +1100 Subject: [PATCH 146/181] clang hates that I guess --- source/frontend/StarVoice.cpp | 16 +++++++--------- source/frontend/StarVoice.hpp | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/source/frontend/StarVoice.cpp b/source/frontend/StarVoice.cpp index 1328846..978bc2c 100644 --- a/source/frontend/StarVoice.cpp +++ b/source/frontend/StarVoice.cpp @@ -387,7 +387,7 @@ void Voice::mix(int16_t* buffer, size_t frameCount, unsigned channels) { mix = true; float volume = speaker->volume; - Array2F levels = speaker->channelVolumes; + std::array levels = speaker->channelVolumes; for (size_t i = 0; i != samples; ++i) sharedBuffer[i] += (int32_t)(speakerBuffer[i]) * levels[i % 2] * volume; //Blends the weaker channel into the stronger one, @@ -438,14 +438,12 @@ void Voice::mix(int16_t* buffer, size_t frameCount, unsigned channels) { void Voice::update(float, PositionalAttenuationFunction positionalAttenuationFunction) { for (auto& entry : m_speakers) { if (SpeakerPtr& speaker = entry.second) { - if (positionalAttenuationFunction) { - speaker->channelVolumes = { - 1.0f - positionalAttenuationFunction(0, speaker->position, 1.0f), - 1.0f - positionalAttenuationFunction(1, speaker->position, 1.0f) - }; - } - else - speaker->channelVolumes = Vec2F::filled(1.0f); + if (positionalAttenuationFunction) { + speaker->channelVolumes = { + 1.0f - positionalAttenuationFunction(0, speaker->position, 1.0f), + 1.0f - positionalAttenuationFunction(1, speaker->position, 1.0f)}; + } else + speaker->channelVolumes = {1.0f, 1.0f}; auto& dbHistory = speaker->dbHistory; memmove(&dbHistory[1], &dbHistory[0], (dbHistory.size() - 1) * sizeof(float)); diff --git a/source/frontend/StarVoice.hpp b/source/frontend/StarVoice.hpp index c914d36..08d01d1 100644 --- a/source/frontend/StarVoice.hpp +++ b/source/frontend/StarVoice.hpp @@ -89,7 +89,7 @@ public: atomic playing = 0; atomic decibelLevel = -96.0f; atomic volume = 1.0f; - atomic> channelVolumes = Array::filled(1); + atomic> channelVolumes = std::array{1.0f, 1.0f}; unsigned int minimumPlaySamples = 4096; From 7b2ce5155adeea78ce9d9c2d533274d9d0ce2109 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 15:27:32 +1100 Subject: [PATCH 147/181] fix Clang warnings those two tryLexicalCasts were literally just broken --- .github/workflows/build.yml | 3 +++ source/core/StarLexicalCast.hpp | 4 ++-- source/core/StarNetElementFloatFields.hpp | 2 +- source/game/StarNetPackets.cpp | 10 +++++----- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8434c80..8d8ce21 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -90,6 +90,9 @@ jobs: build_linux: name: Build OpenStarbound Linux x86_64 runs-on: ubuntu-20.04 + env: + CC: clang + CXX: clang++ steps: - name: Install Packages diff --git a/source/core/StarLexicalCast.hpp b/source/core/StarLexicalCast.hpp index 15afe3f..08dab14 100644 --- a/source/core/StarLexicalCast.hpp +++ b/source/core/StarLexicalCast.hpp @@ -24,12 +24,12 @@ bool tryLexicalCast(bool& result, const char* first, const char* last); template bool tryLexicalCast(Type& result, String const& s) { - return tryLexicalCast(s.utf8Ptr(), s.utf8Ptr() + s.utf8Size()); + return tryLexicalCast(result, s.utf8Ptr(), s.utf8Ptr() + s.utf8Size()); } template bool tryLexicalCast(Type& result, StringView s) { - return tryLexicalCast(s.utf8Ptr(), s.utf8Ptr() + s.utf8Size()); + return tryLexicalCast(result, s.utf8Ptr(), s.utf8Ptr() + s.utf8Size()); } template diff --git a/source/core/StarNetElementFloatFields.hpp b/source/core/StarNetElementFloatFields.hpp index 6c8fbcf..b8ec28f 100644 --- a/source/core/StarNetElementFloatFields.hpp +++ b/source/core/StarNetElementFloatFields.hpp @@ -165,7 +165,7 @@ bool NetElementFloating::writeNetDelta(DataStream& ds, uint64_t fromVersion, } template -void NetElementFloating::readNetDelta(DataStream& ds, float interpolationTime, NetCompatibilityRules rules) { +void NetElementFloating::readNetDelta(DataStream& ds, float interpolationTime, NetCompatibilityRules _rules) { T t = readValue(ds); m_latestUpdateVersion = m_netVersion ? m_netVersion->current() : 0; diff --git a/source/game/StarNetPackets.cpp b/source/game/StarNetPackets.cpp index 44d1e21..e53f988 100644 --- a/source/game/StarNetPackets.cpp +++ b/source/game/StarNetPackets.cpp @@ -85,11 +85,11 @@ EnumMap const NetCompressionModeNames { Packet::~Packet() {} -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) {} +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{}; } PacketCompressionMode Packet::compressionMode() const { return m_compressionMode; } From 3a077eabeb50ae6c0b0410bc7e53a914d81ad1e0 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 15:36:10 +1100 Subject: [PATCH 148/181] make sure vcpkg is using clang --- source/vcpkg-configuration.json | 2 +- toolchains/clang-toolchain.cmake | 2 ++ triplets/x64-linux-mixed.cmake | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 toolchains/clang-toolchain.cmake diff --git a/source/vcpkg-configuration.json b/source/vcpkg-configuration.json index 98aa608..9d30be2 100644 --- a/source/vcpkg-configuration.json +++ b/source/vcpkg-configuration.json @@ -2,7 +2,7 @@ "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg-configuration.schema.json", "default-registry": { "kind": "git", - "baseline": "1de2026f28ead93ff1773e6e680387643e914ea1", + "baseline": "b322364f06308bdd24823f9d8f03fe0cc86fd46f", "repository": "https://github.com/microsoft/vcpkg" } } diff --git a/toolchains/clang-toolchain.cmake b/toolchains/clang-toolchain.cmake new file mode 100644 index 0000000..38a8d38 --- /dev/null +++ b/toolchains/clang-toolchain.cmake @@ -0,0 +1,2 @@ +set(CMAKE_C_COMPILER "/usr/bin/clang") +set(CMAKE_CXX_COMPILER "/usr/bin/clang++") \ No newline at end of file diff --git a/triplets/x64-linux-mixed.cmake b/triplets/x64-linux-mixed.cmake index be80364..5e93dff 100644 --- a/triplets/x64-linux-mixed.cmake +++ b/triplets/x64-linux-mixed.cmake @@ -3,6 +3,7 @@ set(VCPKG_CRT_LINKAGE dynamic) set(VCPKG_LIBRARY_LINKAGE static) set(VCPKG_CMAKE_SYSTEM_NAME Linux) +set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/../toolchains/clang-toolchain.cmake) if(PORT MATCHES "discord-") set(VCPKG_LIBRARY_LINKAGE dynamic) From 6076746ff3fa76e63d953d41885a7d2f843a780e Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 15:51:26 +1100 Subject: [PATCH 149/181] Update build.yml --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8d8ce21..1c14a3d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -98,7 +98,7 @@ jobs: - name: Install Packages run: | sudo apt-get update - sudo apt-get install -y pkg-config libxmu-dev libxi-dev libgl-dev libglu1-mesa-dev libsdl2-dev + sudo apt-get install -y pkg-config libxmu-dev libxi-dev libgl-dev libglu1-mesa-dev libsdl2-dev python3-jinja2 - name: Install CMake & Ninja uses: lukka/get-cmake@latest From aa1d559854a01bbd4cbc6e5d27ca075ab2d9a7c0 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 16:06:10 +1100 Subject: [PATCH 150/181] okay libsystemd doesn't compile on clang right now :( --- .github/workflows/build.yml | 6 +++--- source/CMakePresets.json | 2 -- triplets/x64-linux-mixed.cmake | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1c14a3d..4211cbd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -90,9 +90,9 @@ jobs: build_linux: name: Build OpenStarbound Linux x86_64 runs-on: ubuntu-20.04 - env: - CC: clang - CXX: clang++ + #env: + # CC: clang + # CXX: clang++ steps: - name: Install Packages diff --git a/source/CMakePresets.json b/source/CMakePresets.json index 7efdc23..a2c59e9 100644 --- a/source/CMakePresets.json +++ b/source/CMakePresets.json @@ -47,8 +47,6 @@ "binaryDir": "${sourceParentDir}/build/linux-release", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", - "CMAKE_C_COMPILER": "clang", - "CMAKE_CXX_COMPILER": "clang++", "VCPKG_TARGET_TRIPLET": "x64-linux-mixed", "CMAKE_INCLUDE_PATH": "${sourceParentDir}/lib/linux/include", "CMAKE_LIBRARY_PATH": "${sourceParentDir}/lib/linux", diff --git a/triplets/x64-linux-mixed.cmake b/triplets/x64-linux-mixed.cmake index 5e93dff..545d6f0 100644 --- a/triplets/x64-linux-mixed.cmake +++ b/triplets/x64-linux-mixed.cmake @@ -3,7 +3,7 @@ set(VCPKG_CRT_LINKAGE dynamic) set(VCPKG_LIBRARY_LINKAGE static) set(VCPKG_CMAKE_SYSTEM_NAME Linux) -set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/../toolchains/clang-toolchain.cmake) +# set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/../toolchains/clang-toolchain.cmake) if(PORT MATCHES "discord-") set(VCPKG_LIBRARY_LINKAGE dynamic) From 32f6d28d057a9c8bc8562259766eca06adbc8471 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 17:59:05 +1100 Subject: [PATCH 151/181] trying again --- .github/workflows/build.yml | 8 ++++---- source/CMakePresets.json | 2 ++ triplets/x64-linux-mixed.cmake | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4211cbd..490eef5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -89,10 +89,10 @@ jobs: build_linux: name: Build OpenStarbound Linux x86_64 - runs-on: ubuntu-20.04 - #env: - # CC: clang - # CXX: clang++ + runs-on: ubuntu-22.04 + env: + CC: clang + CXX: clang++ steps: - name: Install Packages diff --git a/source/CMakePresets.json b/source/CMakePresets.json index a2c59e9..7efdc23 100644 --- a/source/CMakePresets.json +++ b/source/CMakePresets.json @@ -47,6 +47,8 @@ "binaryDir": "${sourceParentDir}/build/linux-release", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", + "CMAKE_C_COMPILER": "clang", + "CMAKE_CXX_COMPILER": "clang++", "VCPKG_TARGET_TRIPLET": "x64-linux-mixed", "CMAKE_INCLUDE_PATH": "${sourceParentDir}/lib/linux/include", "CMAKE_LIBRARY_PATH": "${sourceParentDir}/lib/linux", diff --git a/triplets/x64-linux-mixed.cmake b/triplets/x64-linux-mixed.cmake index 545d6f0..5e93dff 100644 --- a/triplets/x64-linux-mixed.cmake +++ b/triplets/x64-linux-mixed.cmake @@ -3,7 +3,7 @@ set(VCPKG_CRT_LINKAGE dynamic) set(VCPKG_LIBRARY_LINKAGE static) set(VCPKG_CMAKE_SYSTEM_NAME Linux) -# set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/../toolchains/clang-toolchain.cmake) +set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/../toolchains/clang-toolchain.cmake) if(PORT MATCHES "discord-") set(VCPKG_LIBRARY_LINKAGE dynamic) From 95b8727d0ca1bacde2612510acb1aba1fc5248b3 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 18:11:52 +1100 Subject: [PATCH 152/181] Update build.yml --- .github/workflows/build.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 490eef5..c7cf799 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,6 +2,19 @@ name: Build on: workflow_dispatch: + inputs: + linux: + type: boolean + description: Linux + default: true + windows: + type: boolean + description: Windows + default: false + macOS: + type: boolean + description: macOS + default: false push: branches: @@ -15,6 +28,7 @@ jobs: build_windows: name: Build OpenStarbound Windows x64 runs-on: windows-latest + if: ${{ (github.event_name != 'workflow_dispatch') || (inputs.windows == true) }} steps: - name: Checkout uses: actions/checkout@v4 @@ -90,6 +104,7 @@ jobs: build_linux: name: Build OpenStarbound Linux x86_64 runs-on: ubuntu-22.04 + if: ${{ (github.event_name != 'workflow_dispatch') || (inputs.linux == true) }} env: CC: clang CXX: clang++ @@ -156,7 +171,7 @@ jobs: build-mac-intel: name: Build OpenStarbound macOS x86_64 runs-on: macos-13 - + if: ${{ (github.event_name != 'workflow_dispatch') || (inputs.macOS == true) }} steps: - uses: actions/checkout@v4 with: @@ -198,7 +213,7 @@ jobs: build-mac-arm: name: Build OpenStarbound macOS arm64 runs-on: macos-14 - + if: ${{ (github.event_name != 'workflow_dispatch') || (inputs.macOS == true) }} steps: - uses: actions/checkout@v4 with: From 4f37d900c476df3f31e2382fa5f6038c9f662c8a Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 18:21:12 +1100 Subject: [PATCH 153/181] get rid of SDL2's dbus dependency --- .github/workflows/build.yml | 8 ++++---- source/vcpkg.json | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c7cf799..73aa3be 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,7 +28,7 @@ jobs: build_windows: name: Build OpenStarbound Windows x64 runs-on: windows-latest - if: ${{ (github.event_name != 'workflow_dispatch') || (inputs.windows == true) }} + if: ${{ (github.event_name == 'workflow_dispatch') && (inputs.windows == true) }} steps: - name: Checkout uses: actions/checkout@v4 @@ -103,7 +103,7 @@ jobs: build_linux: name: Build OpenStarbound Linux x86_64 - runs-on: ubuntu-22.04 + runs-on: ubuntu-20.04 if: ${{ (github.event_name != 'workflow_dispatch') || (inputs.linux == true) }} env: CC: clang @@ -171,7 +171,7 @@ jobs: build-mac-intel: name: Build OpenStarbound macOS x86_64 runs-on: macos-13 - if: ${{ (github.event_name != 'workflow_dispatch') || (inputs.macOS == true) }} + if: ${{ (github.event_name == 'workflow_dispatch') && (inputs.macOS == true) }} steps: - uses: actions/checkout@v4 with: @@ -213,7 +213,7 @@ jobs: build-mac-arm: name: Build OpenStarbound macOS arm64 runs-on: macos-14 - if: ${{ (github.event_name != 'workflow_dispatch') || (inputs.macOS == true) }} + if: ${{ (github.event_name == 'workflow_dispatch') && (inputs.macOS == true) }} steps: - uses: actions/checkout@v4 with: diff --git a/source/vcpkg.json b/source/vcpkg.json index f603aab..ffa41e7 100644 --- a/source/vcpkg.json +++ b/source/vcpkg.json @@ -2,7 +2,8 @@ "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", "dependencies": [ "glew", - "sdl2", + { "name": "sdl2", "default-features": false, "features": ["wayland", "x11", "alsa", "ibus"], "platform": "linux" }, + { "name": "sdl2", "platform": "windows" }, "libvorbis", "zlib", "freetype", From c0fd5c0a606fddda1666c65e4b48e18ef5567fc2 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 18:34:28 +1100 Subject: [PATCH 154/181] Update vcpkg.json --- .github/workflows/build.yml | 2 +- source/vcpkg.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 73aa3be..69ba004 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -113,7 +113,7 @@ jobs: - name: Install Packages run: | sudo apt-get update - sudo apt-get install -y pkg-config libxmu-dev libxi-dev libgl-dev libglu1-mesa-dev libsdl2-dev python3-jinja2 + sudo apt-get install -y pkg-config libxmu-dev libxi-dev libgl-dev libglu1-mesa-dev libsdl2-dev - name: Install CMake & Ninja uses: lukka/get-cmake@latest diff --git a/source/vcpkg.json b/source/vcpkg.json index ffa41e7..bf94fb6 100644 --- a/source/vcpkg.json +++ b/source/vcpkg.json @@ -2,7 +2,7 @@ "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", "dependencies": [ "glew", - { "name": "sdl2", "default-features": false, "features": ["wayland", "x11", "alsa", "ibus"], "platform": "linux" }, + { "name": "sdl2", "default-features": false, "features": ["wayland", "x11", "alsa"], "platform": "linux" }, { "name": "sdl2", "platform": "windows" }, "libvorbis", "zlib", From c14a99a7c329ec4561a22bf78f31f46e0b91bfb4 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 18:55:37 +1100 Subject: [PATCH 155/181] guess I can't have atomic for an array in Clang. ok also the indenting was mixed so I had to fix it which is why the diff here is so wacky --- source/frontend/StarVoice.cpp | 801 +++++++++++++++++----------------- source/frontend/StarVoice.hpp | 2 +- 2 files changed, 404 insertions(+), 399 deletions(-) diff --git a/source/frontend/StarVoice.cpp b/source/frontend/StarVoice.cpp index 978bc2c..8f1b329 100644 --- a/source/frontend/StarVoice.cpp +++ b/source/frontend/StarVoice.cpp @@ -31,71 +31,71 @@ EnumMap const VoiceChannelModeNames{ }; inline float getAudioChunkLoudness(int16_t* data, size_t samples, float volume) { - if (!samples) - return 0.f; + if (!samples) + return 0.f; - double rms = 0.; - for (size_t i = 0; i != samples; ++i) { - float sample = ((float)data[i] / 32767.f) * volume; - rms += (double)(sample * sample); - } + double rms = 0.; + for (size_t i = 0; i != samples; ++i) { + float sample = ((float)data[i] / 32767.f) * volume; + rms += (double)(sample * sample); + } float fRms = sqrtf((float)(rms / samples)); - if (fRms > 0) - return std::clamp(20.f * log10f(fRms), -127.f, 0.f); - else - return -127.f; + if (fRms > 0) + return std::clamp(20.f * log10f(fRms), -127.f, 0.f); + else + return -127.f; } float getAudioLoudness(int16_t* data, size_t samples, float volume = 1.0f) { - constexpr size_t CHUNK_SIZE = 50; + constexpr size_t CHUNK_SIZE = 50; - float highest = -127.f; - for (size_t i = 0; i < samples; i += CHUNK_SIZE) { - float level = getAudioChunkLoudness(data + i, std::min(i + CHUNK_SIZE, samples) - i, volume); - if (level > highest) + float highest = -127.f; + for (size_t i = 0; i < samples; i += CHUNK_SIZE) { + float level = getAudioChunkLoudness(data + i, std::min(i + CHUNK_SIZE, samples) - i, volume); + if (level > highest) highest = level; - } + } - return highest; + return highest; } class VoiceAudioStream { public: // TODO: This should really be a ring buffer instead. std::queue samples; - SDL_AudioStream* sdlAudioStreamMono; - SDL_AudioStream* sdlAudioStreamStereo; + SDL_AudioStream* sdlAudioStreamMono; + SDL_AudioStream* sdlAudioStreamStereo; Mutex mutex; - VoiceAudioStream() - : sdlAudioStreamMono (SDL_NewAudioStream(AUDIO_S16, 1, 48000, AUDIO_S16SYS, 1, 44100)) - , sdlAudioStreamStereo(SDL_NewAudioStream(AUDIO_S16, 2, 48000, AUDIO_S16SYS, 2, 44100)) {}; - ~VoiceAudioStream() { - SDL_FreeAudioStream(sdlAudioStreamMono); - SDL_FreeAudioStream(sdlAudioStreamStereo); - } + VoiceAudioStream() + : sdlAudioStreamMono (SDL_NewAudioStream(AUDIO_S16, 1, 48000, AUDIO_S16SYS, 1, 44100)) + , sdlAudioStreamStereo(SDL_NewAudioStream(AUDIO_S16, 2, 48000, AUDIO_S16SYS, 2, 44100)) {}; + ~VoiceAudioStream() { + SDL_FreeAudioStream(sdlAudioStreamMono); + SDL_FreeAudioStream(sdlAudioStreamStereo); + } - inline int16_t take() { - int16_t sample = 0; - if (!samples.empty()) { - sample = samples.front(); - samples.pop(); - } - return sample; - } + inline int16_t take() { + int16_t sample = 0; + if (!samples.empty()) { + sample = samples.front(); + samples.pop(); + } + return sample; + } - size_t resample(int16_t* in, size_t inSamples, std::vector& out, bool mono) { - SDL_AudioStream* stream = mono ? sdlAudioStreamMono : sdlAudioStreamStereo; - SDL_AudioStreamPut(stream, in, inSamples * sizeof(int16_t)); - if (int available = SDL_AudioStreamAvailable(stream)) { - out.resize(available / 2); - SDL_AudioStreamGet(stream, out.data(), available); - return available; - } - return 0; - } + size_t resample(int16_t* in, size_t inSamples, std::vector& out, bool mono) { + SDL_AudioStream* stream = mono ? sdlAudioStreamMono : sdlAudioStreamStereo; + SDL_AudioStreamPut(stream, in, inSamples * sizeof(int16_t)); + if (int available = SDL_AudioStreamAvailable(stream)) { + out.resize(available / 2); + SDL_AudioStreamGet(stream, out.data(), available); + return available; + } + return 0; + } }; Voice::Speaker::Speaker(SpeakerId id) @@ -106,16 +106,16 @@ Voice::Speaker::Speaker(SpeakerId id) } Json Voice::Speaker::toJson() const { - return JsonObject{ - {"speakerId", speakerId}, - {"entityId", entityId }, - {"name", name }, - {"playing", (bool)playing}, - {"muted", (bool)muted }, - {"decibels", (float)decibelLevel}, - {"smoothDecibels", (float)smoothDb }, - {"position", jsonFromVec2F(position)} - }; + return JsonObject{ + {"speakerId", speakerId}, + {"entityId", entityId }, + {"name", name }, + {"playing", (bool)playing}, + {"muted", (bool)muted }, + {"decibels", (float)decibelLevel}, + {"smoothDecibels", (float)smoothDb }, + {"position", jsonFromVec2F(position)} + }; } Voice* Voice::s_singleton; @@ -140,99 +140,99 @@ Voice::Voice(ApplicationControllerPtr appController) : m_encoder(nullptr, opus_e m_channelMode = VoiceChannelMode::Mono; m_applicationController = appController; - m_stopThread = false; - m_thread = Thread::invoke("Voice::thread", mem_fn(&Voice::thread), this); + m_stopThread = false; + m_thread = Thread::invoke("Voice::thread", mem_fn(&Voice::thread), this); s_singleton = this; } Voice::~Voice() { - m_stopThread = true; + m_stopThread = true; - { - MutexLocker locker(m_threadMutex); - m_threadCond.broadcast(); - } + { + MutexLocker locker(m_threadMutex); + m_threadCond.broadcast(); + } - m_thread.finish(); + m_thread.finish(); - if (m_nextSaveTime) - save(); + if (m_nextSaveTime) + save(); - closeDevice(); + closeDevice(); s_singleton = nullptr; } void Voice::init() { - resetEncoder(); - resetDevice(); + resetEncoder(); + resetDevice(); } template inline bool change(T& value, T newValue, bool& out) { - bool changed = value != newValue; - out |= changed; - value = std::move(newValue); - return changed; + bool changed = value != newValue; + out |= changed; + value = std::move(newValue); + return changed; } void Voice::loadJson(Json const& config, bool skipSave) { // Not all keys are required - bool changed = false; + bool changed = false; - { - bool enabled = shouldEnableInput(); - m_enabled = config.getBool("enabled", m_enabled); - m_inputEnabled = config.getBool("inputEnabled", m_inputEnabled); - if (shouldEnableInput() != enabled) { - changed = true; - resetDevice(); - } - } + { + bool enabled = shouldEnableInput(); + m_enabled = config.getBool("enabled", m_enabled); + m_inputEnabled = config.getBool("inputEnabled", m_inputEnabled); + if (shouldEnableInput() != enabled) { + changed = true; + resetDevice(); + } + } - if (config.contains("deviceName") // Make sure null-type key exists - && change(m_deviceName, config.optString("deviceName"), changed)) - resetDevice(); + if (config.contains("deviceName") // Make sure null-type key exists + && change(m_deviceName, config.optString("deviceName"), changed)) + resetDevice(); m_threshold = config.getFloat("threshold", m_threshold); m_inputAmplitude = perceptualToAmplitude( - m_inputVolume = config.getFloat("inputVolume", m_inputVolume)); + m_inputVolume = config.getFloat("inputVolume", m_inputVolume)); m_outputAmplitude = perceptualToAmplitude( - m_outputVolume = config.getFloat("outputVolume", m_outputVolume)); - - if (change(m_loopback, config.getBool("loopback", m_loopback), changed)) - m_clientSpeaker->playing = false; + m_outputVolume = config.getFloat("outputVolume", m_outputVolume)); + + if (change(m_loopback, config.getBool("loopback", m_loopback), changed)) + m_clientSpeaker->playing = false; - if (auto inputMode = config.optString("inputMode")) { - if (change(m_inputMode, VoiceInputModeNames.getLeft(*inputMode), changed)) - m_lastInputTime = 0; - } + if (auto inputMode = config.optString("inputMode")) { + if (change(m_inputMode, VoiceInputModeNames.getLeft(*inputMode), changed)) + m_lastInputTime = 0; + } - bool shouldResetEncoder = false; - if (auto channelMode = config.optString("channelMode")) { - if (change(m_channelMode, VoiceChannelModeNames.getLeft(*channelMode), changed)) { - closeDevice(); - shouldResetEncoder = true; - resetDevice(); - } - } + bool shouldResetEncoder = false; + if (auto channelMode = config.optString("channelMode")) { + if (change(m_channelMode, VoiceChannelModeNames.getLeft(*channelMode), changed)) { + closeDevice(); + shouldResetEncoder = true; + resetDevice(); + } + } - // not saving this setting to disk, as it's just for audiophiles - // don't want someone fudging their bitrate from the intended defaults and forgetting - if (auto bitrate = config.opt("bitrate")) { + // not saving this setting to disk, as it's just for audiophiles + // don't want someone fudging their bitrate from the intended defaults and forgetting + if (auto bitrate = config.opt("bitrate")) { unsigned newBitrate = bitrate->canConvert(Json::Type::Int) - ? clamp((unsigned)bitrate->toUInt(), 6000u, 510000u) : 0; + ? clamp((unsigned)bitrate->toUInt(), 6000u, 510000u) : 0; shouldResetEncoder |= change(m_bitrate, newBitrate, changed); } if (shouldResetEncoder) resetEncoder(); - if (changed && !skipSave) - scheduleSave(); + if (changed && !skipSave) + scheduleSave(); } @@ -240,14 +240,14 @@ void Voice::loadJson(Json const& config, bool skipSave) { Json Voice::saveJson() const { return JsonObject{ {"enabled", m_enabled}, - {"deviceName", m_deviceName ? *m_deviceName : Json()}, + {"deviceName", m_deviceName ? *m_deviceName : Json()}, {"inputEnabled", m_inputEnabled}, {"threshold", m_threshold}, {"inputVolume", m_inputVolume}, {"outputVolume", m_outputVolume}, {"inputMode", VoiceInputModeNames.getRight(m_inputMode)}, {"channelMode", VoiceChannelModeNames.getRight(m_channelMode)}, - {"loopback", m_loopback}, + {"loopback", m_loopback}, {"version", 1} }; } @@ -261,7 +261,7 @@ void Voice::save() const { void Voice::scheduleSave() { if (!m_nextSaveTime) - m_nextSaveTime = Time::monotonicMilliseconds() + 2000; + m_nextSaveTime = Time::monotonicMilliseconds() + 2000; } Voice::SpeakerPtr Voice::setLocalSpeaker(SpeakerId speakerId) { @@ -273,7 +273,7 @@ Voice::SpeakerPtr Voice::setLocalSpeaker(SpeakerId speakerId) { } Voice::SpeakerPtr Voice::localSpeaker() { - return m_clientSpeaker; + return m_clientSpeaker; } Voice::SpeakerPtr Voice::speaker(SpeakerId speakerId) { @@ -288,176 +288,181 @@ Voice::SpeakerPtr Voice::speaker(SpeakerId speakerId) { } HashMap& Voice::speakers() { - return m_speakers; + return m_speakers; } List Voice::sortedSpeakers(bool onlyPlaying) { - List result; + List result; - auto sorter = [](SpeakerPtr const& a, SpeakerPtr const& b) -> bool { - if (a->lastPlayTime != b->lastPlayTime) - return a->lastPlayTime < b->lastPlayTime; - else - return a->speakerId < b->speakerId; - }; + auto sorter = [](SpeakerPtr const& a, SpeakerPtr const& b) -> bool { + if (a->lastPlayTime != b->lastPlayTime) + return a->lastPlayTime < b->lastPlayTime; + else + return a->speakerId < b->speakerId; + }; - for (auto& p : m_speakers) { - if (!onlyPlaying || p.second->playing) - result.insertSorted(p.second, sorter); - } + for (auto& p : m_speakers) { + if (!onlyPlaying || p.second->playing) + result.insertSorted(p.second, sorter); + } - return result; + return result; } void Voice::clearSpeakers() { - auto it = m_speakers.begin(); - while (it != m_speakers.end()) { - if (it->second == m_clientSpeaker) - it = ++it; - else - it = m_speakers.erase(it); - } + auto it = m_speakers.begin(); + while (it != m_speakers.end()) { + if (it->second == m_clientSpeaker) + it = ++it; + else + it = m_speakers.erase(it); + } } void Voice::readAudioData(uint8_t* stream, int len) { - auto now = Time::monotonicMilliseconds(); - bool active = m_encoder && m_encodedChunksLength < 2048 + auto now = Time::monotonicMilliseconds(); + bool active = m_encoder && m_encodedChunksLength < 2048 && (m_inputMode == VoiceInputMode::VoiceActivity || now < m_lastInputTime); - size_t sampleCount = len / 2; + size_t sampleCount = len / 2; - if (active) { - float decibels = getAudioLoudness((int16_t*)stream, sampleCount); + if (active) { + float decibels = getAudioLoudness((int16_t*)stream, sampleCount); - if (m_inputMode == VoiceInputMode::VoiceActivity) { - if (decibels > m_threshold) - m_lastThresholdTime = now; - active = now - m_lastThresholdTime < 50; - } - } + if (m_inputMode == VoiceInputMode::VoiceActivity) { + if (decibels > m_threshold) + m_lastThresholdTime = now; + active = now - m_lastThresholdTime < 50; + } + } - m_clientSpeaker->decibelLevel = getAudioLoudness((int16_t*)stream, sampleCount, m_inputAmplitude); + m_clientSpeaker->decibelLevel = getAudioLoudness((int16_t*)stream, sampleCount, m_inputAmplitude); - if (!m_loopback) { - if (active && !m_clientSpeaker->playing) - m_clientSpeaker->lastPlayTime = now; + if (!m_loopback) { + if (active && !m_clientSpeaker->playing) + m_clientSpeaker->lastPlayTime = now; - m_clientSpeaker->playing = active; - } + m_clientSpeaker->playing = active; + } - MutexLocker captureLock(m_captureMutex); - if (active) { - m_capturedChunksFrames += sampleCount / m_deviceChannels; - auto data = (opus_int16*)malloc(len); - memcpy(data, stream, len); - m_capturedChunks.emplace(data, sampleCount); // takes ownership - m_threadCond.signal(); - } - else { // Clear out any residual data so they don't manifest at the start of the next encode, whenever that is - while (!m_capturedChunks.empty()) - m_capturedChunks.pop(); + MutexLocker captureLock(m_captureMutex); + if (active) { + m_capturedChunksFrames += sampleCount / m_deviceChannels; + auto data = (opus_int16*)malloc(len); + memcpy(data, stream, len); + m_capturedChunks.emplace(data, sampleCount); // takes ownership + m_threadCond.signal(); + } + else { // Clear out any residual data so they don't manifest at the start of the next encode, whenever that is + while (!m_capturedChunks.empty()) + m_capturedChunks.pop(); - m_capturedChunksFrames = 0; - } + m_capturedChunksFrames = 0; + } } void Voice::mix(int16_t* buffer, size_t frameCount, unsigned channels) { - size_t samples = frameCount * channels; - static std::vector finalBuffer, speakerBuffer; - static std::vector sharedBuffer; //int32 to reduce clipping - speakerBuffer.resize(samples); - sharedBuffer.resize(samples); + size_t samples = frameCount * channels; + static std::vector finalBuffer, speakerBuffer; + static std::vector sharedBuffer; //int32 to reduce clipping + speakerBuffer.resize(samples); + sharedBuffer.resize(samples); - bool mix = false; - { - MutexLocker lock(m_activeSpeakersMutex); - auto it = m_activeSpeakers.begin(); - while (it != m_activeSpeakers.end()) { - SpeakerPtr const& speaker = *it; - VoiceAudioStream* audio = speaker->audioStream.get(); - MutexLocker audioLock(audio->mutex); - if (speaker->playing && !audio->samples.empty()) { - for (size_t i = 0; i != samples; ++i) - speakerBuffer[i] = audio->take(); + bool mix = false; + { + MutexLocker lock(m_activeSpeakersMutex); + auto it = m_activeSpeakers.begin(); + while (it != m_activeSpeakers.end()) { + SpeakerPtr const& speaker = *it; + VoiceAudioStream* audio = speaker->audioStream.get(); + MutexLocker audioLock(audio->mutex); + if (speaker->playing && !audio->samples.empty()) { + for (size_t i = 0; i != samples; ++i) + speakerBuffer[i] = audio->take(); - if (speaker != m_clientSpeaker) - speaker->decibelLevel = getAudioLoudness(speakerBuffer.data(), samples); + if (speaker != m_clientSpeaker) + speaker->decibelLevel = getAudioLoudness(speakerBuffer.data(), samples); - if (!speaker->muted) { - mix = true; + if (!speaker->muted) { + mix = true; - float volume = speaker->volume; - std::array levels = speaker->channelVolumes; - for (size_t i = 0; i != samples; ++i) - sharedBuffer[i] += (int32_t)(speakerBuffer[i]) * levels[i % 2] * volume; - //Blends the weaker channel into the stronger one, - /* unused, is a bit too strong on stereo music. - float maxLevel = max(levels[0], levels[1]); - float leftToRight = maxLevel != 0.0f ? 1.0f - (levels[0] / maxLevel) : 0.0f; - float rightToLeft = maxLevel != 0.0f ? 1.0f - (levels[1] / maxLevel) : 0.0f; + float volume = speaker->volume; + std::array levels; + { + MutexLocker locker(speaker->mutex); + levels = speaker->channelVolumes; + } + for (size_t i = 0; i != samples; ++i) + sharedBuffer[i] += (int32_t)(speakerBuffer[i]) * levels[i % 2] * volume; + //Blends the weaker channel into the stronger one, + /* unused, is a bit too strong on stereo music. + float maxLevel = max(levels[0], levels[1]); + float leftToRight = maxLevel != 0.0f ? 1.0f - (levels[0] / maxLevel) : 0.0f; + float rightToLeft = maxLevel != 0.0f ? 1.0f - (levels[1] / maxLevel) : 0.0f; - int16_t* speakerData = speakerBuffer.data(); - int32_t* sharedData = sharedBuffer.data(); - for (size_t i = 0; i != frameCount; ++i) { - auto leftSample = (float)*speakerData++; - auto rightSample = (float)*speakerData++; - - if (rightToLeft != 0.0f) - leftSample = ( leftSample + rightSample * rightToLeft) / (1.0f + rightToLeft); - if (leftToRight != 0.0f) - rightSample = (rightSample + leftSample * leftToRight) / (1.0f + leftToRight); + int16_t* speakerData = speakerBuffer.data(); + int32_t* sharedData = sharedBuffer.data(); + for (size_t i = 0; i != frameCount; ++i) { + auto leftSample = (float)*speakerData++; + auto rightSample = (float)*speakerData++; + + if (rightToLeft != 0.0f) + leftSample = ( leftSample + rightSample * rightToLeft) / (1.0f + rightToLeft); + if (leftToRight != 0.0f) + rightSample = (rightSample + leftSample * leftToRight) / (1.0f + leftToRight); - *sharedData++ += (int32_t)leftSample * levels[0]; - *sharedData++ += (int32_t)rightSample * levels[1]; - } - //*/ - } - ++it; - } - else { - speaker->playing = false; - if (speaker != m_clientSpeaker) - speaker->decibelLevel = -96.0f; - it = m_activeSpeakers.erase(it); - } - } - } + *sharedData++ += (int32_t)leftSample * levels[0]; + *sharedData++ += (int32_t)rightSample * levels[1]; + } + //*/ + } + ++it; + } + else { + speaker->playing = false; + if (speaker != m_clientSpeaker) + speaker->decibelLevel = -96.0f; + it = m_activeSpeakers.erase(it); + } + } + } - if (mix) { - finalBuffer.resize(sharedBuffer.size(), 0); + if (mix) { + finalBuffer.resize(sharedBuffer.size(), 0); - float vol = m_outputAmplitude; - for (size_t i = 0; i != sharedBuffer.size(); ++i) - finalBuffer[i] = (int16_t)clamp(sharedBuffer[i] * vol, INT16_MIN, INT16_MAX); + float vol = m_outputAmplitude; + for (size_t i = 0; i != sharedBuffer.size(); ++i) + finalBuffer[i] = (int16_t)clamp(sharedBuffer[i] * vol, INT16_MIN, INT16_MAX); - SDL_MixAudioFormat((Uint8*)buffer, (Uint8*)finalBuffer.data(), AUDIO_S16, finalBuffer.size() * sizeof(int16_t), SDL_MIX_MAXVOLUME); - memset(sharedBuffer.data(), 0, sharedBuffer.size() * sizeof(int32_t)); - } + SDL_MixAudioFormat((Uint8*)buffer, (Uint8*)finalBuffer.data(), AUDIO_S16, finalBuffer.size() * sizeof(int16_t), SDL_MIX_MAXVOLUME); + memset(sharedBuffer.data(), 0, sharedBuffer.size() * sizeof(int32_t)); + } } void Voice::update(float, PositionalAttenuationFunction positionalAttenuationFunction) { for (auto& entry : m_speakers) { if (SpeakerPtr& speaker = entry.second) { - if (positionalAttenuationFunction) { - speaker->channelVolumes = { + Vec2F newChannelVolumes = positionalAttenuationFunction ? Vec2F{ 1.0f - positionalAttenuationFunction(0, speaker->position, 1.0f), - 1.0f - positionalAttenuationFunction(1, speaker->position, 1.0f)}; - } else - speaker->channelVolumes = {1.0f, 1.0f}; - - auto& dbHistory = speaker->dbHistory; - memmove(&dbHistory[1], &dbHistory[0], (dbHistory.size() - 1) * sizeof(float)); - dbHistory[0] = speaker->decibelLevel; - float smoothDb = 0.0f; - for (float dB : dbHistory) - smoothDb += dB; + 1.0f - positionalAttenuationFunction(1, speaker->position, 1.0f) + } : Vec2F{1.0f, 1.0f}; + { + MutexLocker locker(speaker->mutex); + speaker->channelVolumes = newChannelVolumes; + } + auto& dbHistory = speaker->dbHistory; + memmove(&dbHistory[1], &dbHistory[0], (dbHistory.size() - 1) * sizeof(float)); + dbHistory[0] = speaker->decibelLevel; + float smoothDb = 0.0f; + for (float dB : dbHistory) + smoothDb += dB; - speaker->smoothDb = smoothDb / dbHistory.size(); + speaker->smoothDb = smoothDb / dbHistory.size(); } } if (m_nextSaveTime && Time::monotonicMilliseconds() > m_nextSaveTime) { - m_nextSaveTime = 0; + m_nextSaveTime = 0; save(); } } @@ -473,122 +478,122 @@ void Voice::setDeviceName(Maybe deviceName) { } StringList Voice::availableDevices() { - int devices = SDL_GetNumAudioDevices(1); - StringList deviceList; - if (devices > 0) { - deviceList.reserve(devices); - for (int i = 0; i != devices; ++i) - deviceList.emplace_back(SDL_GetAudioDeviceName(i, 1)); - } - deviceList.sort(); - return deviceList; + int devices = SDL_GetNumAudioDevices(1); + StringList deviceList; + if (devices > 0) { + deviceList.reserve(devices); + for (int i = 0; i != devices; ++i) + deviceList.emplace_back(SDL_GetAudioDeviceName(i, 1)); + } + deviceList.sort(); + return deviceList; } int Voice::send(DataStreamBuffer& out, size_t budget) { - out.setByteOrder(ByteOrder::LittleEndian); - out.write(VOICE_VERSION); + out.setByteOrder(ByteOrder::LittleEndian); + out.write(VOICE_VERSION); - MutexLocker encodeLock(m_encodeMutex); + MutexLocker encodeLock(m_encodeMutex); - if (m_encodedChunks.empty()) - return 0; + if (m_encodedChunks.empty()) + return 0; - std::vector encodedChunks = std::move(m_encodedChunks); - m_encodedChunksLength = 0; + std::vector encodedChunks = std::move(m_encodedChunks); + m_encodedChunksLength = 0; - encodeLock.unlock(); + encodeLock.unlock(); - for (auto& chunk : encodedChunks) { - out.write(chunk.size()); - out.writeBytes(chunk); - if (budget && (budget -= min(budget, chunk.size())) == 0) - break; - } + for (auto& chunk : encodedChunks) { + out.write(chunk.size()); + out.writeBytes(chunk); + if (budget && (budget -= min(budget, chunk.size())) == 0) + break; + } - m_lastSentTime = Time::monotonicMilliseconds(); - if (m_loopback) - receive(m_clientSpeaker, { out.ptr(), out.size() }); - return 1; + m_lastSentTime = Time::monotonicMilliseconds(); + if (m_loopback) + receive(m_clientSpeaker, { out.ptr(), out.size() }); + return 1; } bool Voice::receive(SpeakerPtr speaker, std::string_view view) { - if (!m_enabled || !speaker || view.empty()) - return false; + if (!m_enabled || !speaker || view.empty()) + return false; - try { - DataStreamExternalBuffer reader(view.data(), view.size()); - reader.setByteOrder(ByteOrder::LittleEndian); + try { + DataStreamExternalBuffer reader(view.data(), view.size()); + reader.setByteOrder(ByteOrder::LittleEndian); - if (reader.read() > VOICE_VERSION) - return false; + if (reader.read() > VOICE_VERSION) + return false; - uint32_t opusLength = 0; - while (!reader.atEnd()) { - reader >> opusLength; - if (reader.pos() + opusLength > reader.size()) - throw VoiceException("Opus packet length goes past end of buffer"s, false); - auto opusData = (unsigned char*)reader.ptr() + reader.pos(); - reader.seek(opusLength, IOSeek::Relative); + uint32_t opusLength = 0; + while (!reader.atEnd()) { + reader >> opusLength; + if (reader.pos() + opusLength > reader.size()) + throw VoiceException("Opus packet length goes past end of buffer"s, false); + auto opusData = (unsigned char*)reader.ptr() + reader.pos(); + reader.seek(opusLength, IOSeek::Relative); - int channels = opus_packet_get_nb_channels(opusData); - if (channels == OPUS_INVALID_PACKET) - continue; + int channels = opus_packet_get_nb_channels(opusData); + if (channels == OPUS_INVALID_PACKET) + continue; - bool mono = channels == 1; - OpusDecoder* decoder = mono ? speaker->decoderMono.get() : speaker->decoderStereo.get(); - int samples = opus_decoder_get_nb_samples(decoder, opusData, opusLength); - if (samples < 0) - throw VoiceException(strf("Decoder error: {}", opus_strerror(samples)), false); + bool mono = channels == 1; + OpusDecoder* decoder = mono ? speaker->decoderMono.get() : speaker->decoderStereo.get(); + int samples = opus_decoder_get_nb_samples(decoder, opusData, opusLength); + if (samples < 0) + throw VoiceException(strf("Decoder error: {}", opus_strerror(samples)), false); - m_decodeBuffer.resize(samples * (size_t)channels); + m_decodeBuffer.resize(samples * (size_t)channels); - int decodedSamples = opus_decode(decoder, opusData, opusLength, m_decodeBuffer.data(), m_decodeBuffer.size() * sizeof(int16_t), 0); - if (decodedSamples <= 0) { - if (decodedSamples < 0) - throw VoiceException(strf("Decoder error: {}", opus_strerror(samples)), false); - return true; - } + int decodedSamples = opus_decode(decoder, opusData, opusLength, m_decodeBuffer.data(), m_decodeBuffer.size() * sizeof(int16_t), 0); + if (decodedSamples <= 0) { + if (decodedSamples < 0) + throw VoiceException(strf("Decoder error: {}", opus_strerror(samples)), false); + return true; + } - //Logger::info("Voice: decoded Opus chunk {} bytes -> {} samples", opusLength, decodedSamples * channels); + //Logger::info("Voice: decoded Opus chunk {} bytes -> {} samples", opusLength, decodedSamples * channels); - speaker->audioStream->resample(m_decodeBuffer.data(), (size_t)decodedSamples * channels, m_resampleBuffer, mono); + speaker->audioStream->resample(m_decodeBuffer.data(), (size_t)decodedSamples * channels, m_resampleBuffer, mono); - { - MutexLocker lock(speaker->audioStream->mutex); - auto& samples = speaker->audioStream->samples; + { + MutexLocker lock(speaker->audioStream->mutex); + auto& samples = speaker->audioStream->samples; - auto now = Time::monotonicMilliseconds(); - if (now - speaker->lastReceiveTime < 1000) { - auto limit = (size_t)speaker->minimumPlaySamples + 22050; - if (samples.size() > limit) { // skip ahead if we're getting too far - for (size_t i = samples.size(); i >= limit; --i) - samples.pop(); - } - } - else - samples = std::queue(); + auto now = Time::monotonicMilliseconds(); + if (now - speaker->lastReceiveTime < 1000) { + auto limit = (size_t)speaker->minimumPlaySamples + 22050; + if (samples.size() > limit) { // skip ahead if we're getting too far + for (size_t i = samples.size(); i >= limit; --i) + samples.pop(); + } + } + else + samples = std::queue(); - speaker->lastReceiveTime = now; + speaker->lastReceiveTime = now; - if (mono) { - for (int16_t sample : m_resampleBuffer) { - samples.push(sample); - samples.push(sample); - } - } - else { - for (int16_t sample : m_resampleBuffer) - samples.push(sample); - } - } - playSpeaker(speaker, channels); - } - return true; - } - catch (StarException const& e) { - Logger::error("Voice: Error receiving voice data for speaker #{} ('{}'): {}", speaker->speakerId, speaker->name, e.what()); - return false; - } + if (mono) { + for (int16_t sample : m_resampleBuffer) { + samples.push(sample); + samples.push(sample); + } + } + else { + for (int16_t sample : m_resampleBuffer) + samples.push(sample); + } + } + playSpeaker(speaker, channels); + } + return true; + } + catch (StarException const& e) { + Logger::error("Voice: Error receiving voice data for speaker #{} ('{}'): {}", speaker->speakerId, speaker->name, e.what()); + return false; + } } void Voice::setInput(bool input) { @@ -615,31 +620,31 @@ OpusEncoder* Voice::createEncoder(int channels) { void Voice::resetEncoder() { int channels = encoderChannels(); - MutexLocker locker(m_threadMutex); + MutexLocker locker(m_threadMutex); m_encoder.reset(createEncoder(channels)); - int bitrate = m_bitrate > 0 ? (int)m_bitrate : (channels == 2 ? 50000 : 24000); + int bitrate = m_bitrate > 0 ? (int)m_bitrate : (channels == 2 ? 50000 : 24000); opus_encoder_ctl(m_encoder.get(), OPUS_SET_BITRATE(bitrate)); } void Voice::resetDevice() { - if (shouldEnableInput()) - openDevice(); - else - closeDevice(); + if (shouldEnableInput()) + openDevice(); + else + closeDevice(); } void Voice::openDevice() { closeDevice(); m_applicationController->openAudioInputDevice( - m_deviceName ? m_deviceName->utf8Ptr() : nullptr, - VOICE_SAMPLE_RATE, - m_deviceChannels = encoderChannels(), - this, - [](void* userdata, uint8_t* stream, int len) { + m_deviceName ? m_deviceName->utf8Ptr() : nullptr, + VOICE_SAMPLE_RATE, + m_deviceChannels = encoderChannels(), + this, + [](void* userdata, uint8_t* stream, int len) { ((Voice*)(userdata))->readAudioData(stream, len); } - ); + ); m_deviceOpen = true; } @@ -649,81 +654,81 @@ void Voice::closeDevice() { return; m_applicationController->closeAudioInputDevice(); - m_clientSpeaker->playing = false; - m_clientSpeaker->decibelLevel = -96.0f; + m_clientSpeaker->playing = false; + m_clientSpeaker->decibelLevel = -96.0f; m_deviceOpen = false; } bool Voice::playSpeaker(SpeakerPtr const& speaker, int) { - if (speaker->playing || speaker->audioStream->samples.size() < speaker->minimumPlaySamples) - return false; + if (speaker->playing || speaker->audioStream->samples.size() < speaker->minimumPlaySamples) + return false; - if (!speaker->playing) { - speaker->lastPlayTime = Time::monotonicMilliseconds(); - speaker->playing = true; - MutexLocker lock(m_activeSpeakersMutex); - m_activeSpeakers.insert(speaker); - } - return true; + if (!speaker->playing) { + speaker->lastPlayTime = Time::monotonicMilliseconds(); + speaker->playing = true; + MutexLocker lock(m_activeSpeakersMutex); + m_activeSpeakers.insert(speaker); + } + return true; } void Voice::thread() { - while (true) { - MutexLocker locker(m_threadMutex); + while (true) { + MutexLocker locker(m_threadMutex); - m_threadCond.wait(m_threadMutex); - if (m_stopThread) - return; + m_threadCond.wait(m_threadMutex); + if (m_stopThread) + return; - { - MutexLocker locker(m_captureMutex); - ByteArray encoded(VOICE_MAX_PACKET_SIZE, 0); - size_t frameSamples = VOICE_FRAME_SIZE * (size_t)m_deviceChannels; - while (m_capturedChunksFrames >= VOICE_FRAME_SIZE) { - std::vector samples; - samples.reserve(frameSamples); - size_t samplesLeft = frameSamples; - while (samplesLeft && !m_capturedChunks.empty()) { - auto& front = m_capturedChunks.front(); - if (front.exhausted()) - m_capturedChunks.pop(); - else - samplesLeft -= front.takeSamples(samples, samplesLeft); - } - m_capturedChunksFrames -= VOICE_FRAME_SIZE; + { + MutexLocker locker(m_captureMutex); + ByteArray encoded(VOICE_MAX_PACKET_SIZE, 0); + size_t frameSamples = VOICE_FRAME_SIZE * (size_t)m_deviceChannels; + while (m_capturedChunksFrames >= VOICE_FRAME_SIZE) { + std::vector samples; + samples.reserve(frameSamples); + size_t samplesLeft = frameSamples; + while (samplesLeft && !m_capturedChunks.empty()) { + auto& front = m_capturedChunks.front(); + if (front.exhausted()) + m_capturedChunks.pop(); + else + samplesLeft -= front.takeSamples(samples, samplesLeft); + } + m_capturedChunksFrames -= VOICE_FRAME_SIZE; - if (m_inputAmplitude != 1.0f) { - for (size_t i = 0; i != samples.size(); ++i) - samples[i] *= m_inputAmplitude; - } + if (m_inputAmplitude != 1.0f) { + for (size_t i = 0; i != samples.size(); ++i) + samples[i] *= m_inputAmplitude; + } - if (int encodedSize = opus_encode(m_encoder.get(), samples.data(), VOICE_FRAME_SIZE, (unsigned char*)encoded.ptr(), encoded.size())) { - if (encodedSize == 1) - continue; + if (int encodedSize = opus_encode(m_encoder.get(), samples.data(), VOICE_FRAME_SIZE, (unsigned char*)encoded.ptr(), encoded.size())) { + if (encodedSize == 1) + continue; - encoded.resize(encodedSize); + encoded.resize(encodedSize); - { - MutexLocker lock(m_encodeMutex); - m_encodedChunks.emplace_back(std::move(encoded)); - m_encodedChunksLength += encodedSize; + { + MutexLocker locker(m_encodeMutex); + m_encodedChunks.emplace_back(std::move(encoded)); + m_encodedChunksLength += encodedSize; - encoded = ByteArray(VOICE_MAX_PACKET_SIZE, 0); - } + encoded = ByteArray(VOICE_MAX_PACKET_SIZE, 0); + } - //Logger::info("Voice: encoded Opus chunk {} samples -> {} bytes", frameSamples, encodedSize); - } - else if (encodedSize < 0) - Logger::error("Voice: Opus encode error {}", opus_strerror(encodedSize)); - } - } + //Logger::info("Voice: encoded Opus chunk {} samples -> {} bytes", frameSamples, encodedSize); + } + else if (encodedSize < 0) + Logger::error("Voice: Opus encode error {}", opus_strerror(encodedSize)); + } + } - continue; + continue; - locker.unlock(); - Thread::yield(); - } - return; + locker.unlock(); + Thread::yield(); + } + return; } } \ No newline at end of file diff --git a/source/frontend/StarVoice.hpp b/source/frontend/StarVoice.hpp index 08d01d1..59daeaa 100644 --- a/source/frontend/StarVoice.hpp +++ b/source/frontend/StarVoice.hpp @@ -89,7 +89,7 @@ public: atomic playing = 0; atomic decibelLevel = -96.0f; atomic volume = 1.0f; - atomic> channelVolumes = std::array{1.0f, 1.0f}; + Vec2F channelVolumes = Vec2F::filled(1.f); unsigned int minimumPlaySamples = 4096; From da76c1d95d7daaa5290728ef6834baf2185bb03c Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 19:06:37 +1100 Subject: [PATCH 156/181] defer test to after upload so I can debug locally --- .github/workflows/build.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 69ba004..1ffe0aa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -144,7 +144,6 @@ jobs: cmakeListsTxtPath: '${{ github.workspace }}/source/CMakeLists.txt' configurePreset: 'linux-release' buildPreset: 'linux-release' - testPreset: 'linux-release' - name: Assemble Files working-directory: ${{ github.workspace }} @@ -156,6 +155,12 @@ jobs: name: OpenStarbound-Linux path: dist.tar + - name: Run Tests + uses: lukka/run-cmake@v10 + with: + cmakeListsTxtPath: '${{ github.workspace }}/source/CMakeLists.txt' + testPreset: 'linux-release' + - name: Upload Client Files uses: actions/upload-artifact@v4 with: From d922be661241b1d8140ddc9d436fd188d5e514ce Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 19:11:20 +1100 Subject: [PATCH 157/181] decouple raw artifacts from assemble script --- .github/workflows/build.yml | 8 ++++++-- scripts/ci/linux/assemble.sh | 1 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1ffe0aa..f263aa1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -145,9 +145,9 @@ jobs: configurePreset: 'linux-release' buildPreset: 'linux-release' - - name: Assemble Files + - name: Prepare Artifacts working-directory: ${{ github.workspace }} - run: scripts/ci/linux/assemble.sh + run: tar -cvf dist.tar dist - name: Upload Artifacts uses: actions/upload-artifact@v4 @@ -161,6 +161,10 @@ jobs: cmakeListsTxtPath: '${{ github.workspace }}/source/CMakeLists.txt' testPreset: 'linux-release' + - name: Assemble Files + working-directory: ${{ github.workspace }} + run: scripts/ci/linux/assemble.sh + - name: Upload Client Files uses: actions/upload-artifact@v4 with: diff --git a/scripts/ci/linux/assemble.sh b/scripts/ci/linux/assemble.sh index 1b4970a..1b3eb9f 100755 --- a/scripts/ci/linux/assemble.sh +++ b/scripts/ci/linux/assemble.sh @@ -51,6 +51,5 @@ cp \ scripts/steam_appid.txt \ server_distribution/linux/ -tar -cvf dist.tar dist tar -cvf client.tar client_distribution tar -cvf server.tar server_distribution From cb893f0f526fb8b508cbfa17fb6c58648390b28a Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 19:20:40 +1100 Subject: [PATCH 158/181] disable jemalloc on Linux for Clang --- source/CMakePresets.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/CMakePresets.json b/source/CMakePresets.json index 7efdc23..fbd2035 100644 --- a/source/CMakePresets.json +++ b/source/CMakePresets.json @@ -53,7 +53,7 @@ "CMAKE_INCLUDE_PATH": "${sourceParentDir}/lib/linux/include", "CMAKE_LIBRARY_PATH": "${sourceParentDir}/lib/linux", "STAR_ENABLE_STATIC_LIBGCC_LIBSTDCXX": true, - "STAR_USE_JEMALLOC": true + "STAR_USE_JEMALLOC": false }, "vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { From 5247c4855174bdfe3db741f8de18e54d37fb89da Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 19:41:40 +1100 Subject: [PATCH 159/181] actually silence Clang unused warns [skip ci] --- source/core/StarNetElementFloatFields.hpp | 3 ++- source/game/StarNetPackets.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/source/core/StarNetElementFloatFields.hpp b/source/core/StarNetElementFloatFields.hpp index b8ec28f..44e0a89 100644 --- a/source/core/StarNetElementFloatFields.hpp +++ b/source/core/StarNetElementFloatFields.hpp @@ -165,7 +165,8 @@ bool NetElementFloating::writeNetDelta(DataStream& ds, uint64_t fromVersion, } template -void NetElementFloating::readNetDelta(DataStream& ds, float interpolationTime, NetCompatibilityRules _rules) { +void NetElementFloating::readNetDelta(DataStream& ds, float interpolationTime, NetCompatibilityRules rules) { + _unused(rules) T t = readValue(ds); m_latestUpdateVersion = m_netVersion ? m_netVersion->current() : 0; diff --git a/source/game/StarNetPackets.cpp b/source/game/StarNetPackets.cpp index e53f988..2e64eee 100644 --- a/source/game/StarNetPackets.cpp +++ b/source/game/StarNetPackets.cpp @@ -85,11 +85,11 @@ EnumMap const NetCompressionModeNames { Packet::~Packet() {} -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) {} +void Packet::read(DataStream& ds, NetCompatibilityRules netRules) { read(ds); _unused(netRules); } +void Packet::read(DataStream& ds) { _unused(ds); } +void Packet::write(DataStream& ds, NetCompatibilityRules netRules) const { write(ds); _unused(netRules); } +void Packet::write(DataStream& ds) const { _unused(ds); } +void Packet::readJson(Json const& json) { _unused(json); } Json Packet::writeJson() const { return JsonObject{}; } PacketCompressionMode Packet::compressionMode() const { return m_compressionMode; } From c37265623d35bc399c8e673ad62cd34892d60d46 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 20:13:23 +1100 Subject: [PATCH 160/181] oops [skip ci] --- source/core/StarNetElementFloatFields.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/StarNetElementFloatFields.hpp b/source/core/StarNetElementFloatFields.hpp index 44e0a89..97cacb7 100644 --- a/source/core/StarNetElementFloatFields.hpp +++ b/source/core/StarNetElementFloatFields.hpp @@ -166,7 +166,7 @@ bool NetElementFloating::writeNetDelta(DataStream& ds, uint64_t fromVersion, template void NetElementFloating::readNetDelta(DataStream& ds, float interpolationTime, NetCompatibilityRules rules) { - _unused(rules) + _unused(rules); T t = readValue(ds); m_latestUpdateVersion = m_netVersion ? m_netVersion->current() : 0; From ad1c25a502c72a0940691d3e1e3811afbb3d6b9f Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 20:31:15 +1100 Subject: [PATCH 161/181] Update vcpkg.json [skip ci] --- source/vcpkg.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/vcpkg.json b/source/vcpkg.json index bf94fb6..7cd9591 100644 --- a/source/vcpkg.json +++ b/source/vcpkg.json @@ -2,7 +2,7 @@ "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", "dependencies": [ "glew", - { "name": "sdl2", "default-features": false, "features": ["wayland", "x11", "alsa"], "platform": "linux" }, + { "name": "sdl2", "default-features": false, "features": ["wayland", "x11", "alsa"], "platform": "!windows" }, { "name": "sdl2", "platform": "windows" }, "libvorbis", "zlib", From a589a41fb49dacdbef0186f9ee389ea189c083f4 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 31 Dec 2024 20:40:42 +1100 Subject: [PATCH 162/181] Update vcpkg.json [skip ci] --- source/vcpkg.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/vcpkg.json b/source/vcpkg.json index 7cd9591..6eab46c 100644 --- a/source/vcpkg.json +++ b/source/vcpkg.json @@ -2,8 +2,8 @@ "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", "dependencies": [ "glew", - { "name": "sdl2", "default-features": false, "features": ["wayland", "x11", "alsa"], "platform": "!windows" }, - { "name": "sdl2", "platform": "windows" }, + { "name": "sdl2", "default-features": false, "features": ["wayland", "x11", "alsa"], "platform": "linux" }, + { "name": "sdl2", "platform": "!linux" }, "libvorbis", "zlib", "freetype", From 5159b073bd9e3d2b903df27188b6b42db1ac65c7 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Wed, 1 Jan 2025 19:41:42 +1100 Subject: [PATCH 163/181] /render: support for rendering out character and clothing sheets --- .../avian-tier6separator/old/bsleeve.png | Bin 0 -> 2488 bytes .../avian/avian-tier6separator/old/chestf.png | Bin 0 -> 557 bytes .../avian/avian-tier6separator/old/chestm.png | Bin 0 -> 606 bytes .../avian-tier6separator/old/fsleeve.png | Bin 0 -> 2320 bytes .../frontend/StarClientCommandProcessor.cpp | 150 +++++++++++++++++- source/game/StarHumanoid.cpp | 40 +++++ source/game/StarHumanoid.hpp | 32 ++-- 7 files changed, 208 insertions(+), 14 deletions(-) create mode 100644 assets/opensb/items/armors/avian/avian-tier6separator/old/bsleeve.png create mode 100644 assets/opensb/items/armors/avian/avian-tier6separator/old/chestf.png create mode 100644 assets/opensb/items/armors/avian/avian-tier6separator/old/chestm.png create mode 100644 assets/opensb/items/armors/avian/avian-tier6separator/old/fsleeve.png diff --git a/assets/opensb/items/armors/avian/avian-tier6separator/old/bsleeve.png b/assets/opensb/items/armors/avian/avian-tier6separator/old/bsleeve.png new file mode 100644 index 0000000000000000000000000000000000000000..7d527485d705d293be0febcba808b9f8818457df GIT binary patch literal 2488 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 literal 0 HcmV?d00001 diff --git a/assets/opensb/items/armors/avian/avian-tier6separator/old/fsleeve.png b/assets/opensb/items/armors/avian/avian-tier6separator/old/fsleeve.png new file mode 100644 index 0000000000000000000000000000000000000000..db91be2858d7d1f22a4a402eebcf49bcc1b94064 GIT binary patch literal 2320 zcmV+r3GeoaP)hKmY&$!|1tO00001bW%=J06^y0W&i*Prb$FWRCwC$-7#+) zOR~lBe<1dW4LyB<3qrY}$6WR`6ptYA#k_oD#wV+*IiyLR@->XB>O^yH*S_z>zC5L?oJw^aI<#E zi{4sygPaCKOTRlE7(SAqS_yDEh zK5lNZEANu(YHVK+HrqESrz=&(DkzEJ=Kj03+sHg|L|tA@uK$HRCEE z#E0qE=c4RbyzwIMb#;G=^Fj#)67uo=^2N>XRd0*PdBS0vgg^onCU>l!O}6#BBFGa? zsuU0?z=c8Vs~rsOxmKK5^V;EI;xD8$!dPu~Xn9-2yCReilOhaT)fz^5TxkGSnI%-q5yNCTRI+tIZDiD!wzq)%E9rqWWleliDKoyZ1%-yrHf< z+H?NQw(aMDZTbK8^<|sv&YNNv#`ut5cvkIG(iZT~-B9boc>0`QcwX5ko<0q=E{w

    KDAuIsw4>%uIZB`KC40kdG?#YeD+`6F~)Z(xAA z8yM#2U!R#Rqk*B_Q#ZYVfeE*pe3m@DfnoZLUENQQF!PM<^9bwNBeaPT#x>K`8yLph z;^R2h2ir~+0VGg*I$3WCNUqF}LF*zG>P;L});1 zX%5tk4_w~TOg}@tl%?5{$WL-F)R()Vv}c|+T&Q+^J(Tv$YT!bx9≥vm~pbzGoJk zs_VM0>$W@)V7BLrxv&q5H$f-rxst_$W?KaSp} zRV2w)FrP6QYxbaiGKb27vA^Q{HuBd+J8D>4!<>o z`u8tDyQO~Yd?53l2nGy3I??Ay;rkbo(H4Tym?Z451LLC;{o?khZ{>E+fs-&8Tv^># zE9O>D|FdH`vcJQA`n=)1+IB+!LH2jpk2fca5C&|HeEB?ly#FBkJM7gka3V&5T{!t3 zA8P#vXa76wz`}m@@ZHoVJU>g`a!yVouo{XJJ}^5Y+a~en9Nu@G0s_LwER#S0#$urY z1qfsoN(dvcSSDEn7M58m0S41`T{ow&&7uhm;AKZ}h*)-nAC~)-j1a`7MCiJ%GaxTMg2j?q(O2Ou{aNU`uIsw4>$ZY1_&eZAqqguLtsn@gg)8^V1$s(90LD8BcrflM}XOJDINO5e&wGWTMj1VDU4n-xI+E z$#hNev%$ewA;OBnzeaXI*Q|nW>iU=dkHP5pRLcm= ztW=4BWd&grC|;auDJZskC}v#+OW2aI1pwh6C0uQG@Qe{~62ZEV2#V4*vVyRL6#x)^ z-bl7)*ho|8jVb=drISfS-Y2k3^G9g+`7XAPr&~q>@X>Ml{UuJK30npW^Gry9EahD! zGig~{g@x@v@p}ZLK!K&aqhKcO>zX`5@NyLd2*CKbi==Ag6vn@H9Qp0v3B=LyC@ApD zowS?z(QoyQkhd<;ZfA*5-v|YVNe>=Oci3?z^Zx=yQ{Nr3pFIKs5Wj2Rc9e~`%*`k; zzgykiP}WWpVSJ!WfOui`X`pVu;{?(cwww$oj#goyuAL;p;|-H+ncdTd6DmCU)2#;1 qB;Rw3vih`PZhaNl(sf;Tq5cJ;#DfF>!cwgO0000image(imagePath); - image->writePng(File::open("render.png", IOMode::Write)); +// Hardcoded render command, future version will write to the clipboard and possibly be implemented in Lua +String ClientCommandProcessor::render(String const& path) { + if (path.empty()) { + return "Specify a path to render an image, or for worn armor: " + "^cyan;hat^reset;/^cyan;chest^reset;/^cyan;legs^reset;/^cyan;back^reset; " + "or for body parts: " + "^cyan;head^reset;/^cyan;body^reset;/^cyan;hair^reset;/^cyan;facialhair^reset;/" + "^cyan;facialmask^reset;/^cyan;frontarm^reset;/^cyan;backarm^reset;/^cyan;emote^reset;"; + } + AssetPath assetPath; + bool outputSheet = false; + String outputName = "render"; + auto player = m_universeClient->mainPlayer(); + if (player && path.utf8Size() < 100) { + auto args = m_parser.tokenizeToStringList(path); + auto first = args.maybeFirst().value().toLower(); + auto humanoid = player->humanoid(); + auto& identity = humanoid->identity(); + auto species = identity.imagePath.value(identity.species); + outputSheet = true; + outputName = first; + if (first.equals("hat")) { + assetPath.basePath = humanoid->headArmorFrameset(); + assetPath.directives += humanoid->headArmorDirectives(); + } else if (first.equals("chest")) { + if (args.size() <= 1) { + return "Chest armors have multiple spritesheets. Do: " + "^white;/chest torso ^cyan;front^reset;/^cyan;torso^reset;/^cyan;back^reset;. " + "To repair old generated clothes, then also specify ^cyan;old^reset;."; + } + String sheet = args[1].toLower(); + outputName += " " + sheet; + if (sheet == "torso") { + assetPath.basePath = humanoid->chestArmorFrameset(); + assetPath.directives += humanoid->chestArmorDirectives(); + } else if (sheet == "front") { + assetPath.basePath = humanoid->frontSleeveFrameset(); + assetPath.directives += humanoid->chestArmorDirectives(); + } else if (sheet == "back") { + assetPath.basePath = humanoid->backSleeveFrameset(); + assetPath.directives += humanoid->chestArmorDirectives(); + } else { + return strf("^red;Invalid chest sheet type '{}'^reset;", sheet); + } + // recovery for custom chests made by a very old generator + if (args.size() <= 2 && args[2].toLower() == "old" && assetPath.basePath.beginsWith("/items/armors/avian/avian-tier6separator/")) + assetPath.basePath = "/items/armors/avian/avian-tier6separator/old/" + assetPath.basePath.substr(41); + } else if (first.equals("legs")) { + assetPath.basePath = humanoid->legsArmorFrameset(); + assetPath.directives += humanoid->legsArmorDirectives(); + } else if (first.equals("back")) { + assetPath.basePath = humanoid->backArmorFrameset(); + assetPath.directives += humanoid->backArmorDirectives(); + } else if (first.equals("body")) { + assetPath.basePath = humanoid->getBodyFromIdentity(); + assetPath.directives += identity.bodyDirectives; + } else if (first.equals("head")) { + outputSheet = false; + assetPath.basePath = humanoid->getHeadFromIdentity(); + assetPath.directives += identity.bodyDirectives; + } else if (first.equals("hair")) { + outputSheet = false; + assetPath.basePath = humanoid->getHairFromIdentity(); + assetPath.directives += identity.hairDirectives; + } else if (first.equals("facialhair")) { + outputSheet = false; + assetPath.basePath = humanoid->getFacialHairFromIdentity(); + assetPath.directives += identity.facialHairDirectives; + } else if (first.equals("facialmask")) { + outputSheet = false; + assetPath.basePath = humanoid->getFacialMaskFromIdentity(); + assetPath.directives += identity.facialMaskDirectives; + } else if (first.equals("frontarm")) { + assetPath.basePath = humanoid->getFrontArmFromIdentity(); + assetPath.directives += identity.bodyDirectives; + } else if (first.equals("backarm")) { + assetPath.basePath = humanoid->getBackArmFromIdentity(); + assetPath.directives += identity.bodyDirectives; + } else if (first.equals("emote")) { + assetPath.basePath = humanoid->getFacialEmotesFromIdentity(); + assetPath.directives += identity.emoteDirectives; + } else { + outputName = "render"; + } + + if (!outputSheet) + assetPath.subPath = String("normal"); + } + if (assetPath == AssetPath()) { + assetPath = AssetPath::split(path); + if (!assetPath.basePath.beginsWith("/")) + assetPath.basePath = "/assetmissing.png" + assetPath.basePath; + } + auto assets = Root::singleton().assets(); + ImageConstPtr image; + if (outputSheet) { + auto sheet = make_shared(*assets->image(assetPath.basePath)); + sheet->convert(PixelFormat::RGBA32); + AssetPath framePath = assetPath; + + StringMap> frames; + auto imageFrames = assets->imageFrames(assetPath.basePath); + for (auto& pair : imageFrames->frames) + frames[pair.first] = make_pair(pair.second, ImageConstPtr()); + + if (frames.empty()) + return "^red;Failed to save image^reset;"; + + for (auto& entry : frames) { + framePath.subPath = entry.first; + entry.second.second = assets->image(framePath); + } + + Vec2U frameSize = frames.begin()->second.first.size(); + Vec2U imageSize = frames.begin()->second.second->size().piecewiseMin(Vec2U{256, 256}); + if (imageSize.min() == 0) + return "^red;Resulting image is empty^reset;"; + + for (auto& frame : frames) { + RectU& box = frame.second.first; + box.setXMin((box.xMin() / frameSize[0]) * imageSize[0]); + box.setYMin(((sheet->height() - box.yMin() - box.height()) / frameSize[1]) * imageSize[1]); + box.setXMax(box.xMin() + imageSize[0]); + box.setYMax(box.yMin() + imageSize[1]); + } + + if (frameSize != imageSize) { + unsigned sheetWidth = (sheet->width() / frameSize[0]) * imageSize[0]; + unsigned sheetHeight = (sheet->height() / frameSize[0]) * imageSize[0]; + sheet->reset(sheetWidth, sheetHeight, PixelFormat::RGBA32); + } + + for (auto& entry : frames) + sheet->copyInto(entry.second.first.min(), *entry.second.second); + + image = std::move(sheet); + } else { + image = assets->image(assetPath); + } + if (image->size().min() == 0) + return "^red;Resulting image is empty^reset;"; + auto outputDirectory = Root::singleton().toStoragePath("output"); + auto outputPath = File::relativeTo(outputDirectory, strf("{}.png", outputName)); + if (!File::isDirectory(outputDirectory)) + File::makeDirectory(outputDirectory); + image->writePng(File::open(outputPath, IOMode::Write | IOMode::Truncate)); return strf("Saved {}x{} image to render.png", image->width(), image->height()); } diff --git a/source/game/StarHumanoid.cpp b/source/game/StarHumanoid.cpp index 97b90cd..2acc632 100644 --- a/source/game/StarHumanoid.cpp +++ b/source/game/StarHumanoid.cpp @@ -390,6 +390,46 @@ void Humanoid::setHelmetMaskDirectives(Directives helmetMaskDirectives) { m_helmetMaskDirectives = std::move(helmetMaskDirectives); } +Directives const& Humanoid::headArmorDirectives() const { + return m_headArmorDirectives; +}; + +String const& Humanoid::headArmorFrameset() const { + return m_headArmorFrameset; +}; + +Directives const& Humanoid::chestArmorDirectives() const { + return m_chestArmorDirectives; +}; + +String const& Humanoid::chestArmorFrameset() const { + return m_chestArmorFrameset; +}; + +String const& Humanoid::backSleeveFrameset() const { + return m_backSleeveFrameset; +}; + +String const& Humanoid::frontSleeveFrameset() const { + return m_frontSleeveFrameset; +}; + +Directives const& Humanoid::legsArmorDirectives() const { + return m_legsArmorDirectives; +}; + +String const& Humanoid::legsArmorFrameset() const { + return m_legsArmorFrameset; +}; + +Directives const& Humanoid::backArmorDirectives() const { + return m_backArmorDirectives; +}; + +String const& Humanoid::backArmorFrameset() const { + return m_backArmorFrameset; +}; + void Humanoid::setBodyHidden(bool hidden) { m_bodyHidden = hidden; } diff --git a/source/game/StarHumanoid.hpp b/source/game/StarHumanoid.hpp index 98412f2..d43c5ef 100644 --- a/source/game/StarHumanoid.hpp +++ b/source/game/StarHumanoid.hpp @@ -158,6 +158,18 @@ public: void setHelmetMaskDirectives(Directives helmetMaskDirectives); + // Getters for all of the above + Directives const& headArmorDirectives() const; + String const& headArmorFrameset() const; + Directives const& chestArmorDirectives() const; + String const& chestArmorFrameset() const; + String const& backSleeveFrameset() const; + String const& frontSleeveFrameset() const; + Directives const& legsArmorDirectives() const; + String const& legsArmorFrameset() const; + Directives const& backArmorDirectives() const; + String const& backArmorFrameset() const; + void setBodyHidden(bool hidden); void setState(State state); @@ -247,6 +259,16 @@ public: List particles(String const& name) const; Json const& defaultMovementParameters() const; + + String getHeadFromIdentity() const; + String getBodyFromIdentity() const; + String getFacialEmotesFromIdentity() const; + String getHairFromIdentity() const; + String getFacialHairFromIdentity() const; + String getFacialMaskFromIdentity() const; + String getBackArmFromIdentity() const; + String getFrontArmFromIdentity() const; + String getVaporTrailFrameset() const; // Extracts scalenearest from directives and returns the combined scale and // a new Directives without those scalenearest directives. @@ -269,16 +291,6 @@ private: String frameBase(State state) const; String emoteFrameBase(HumanoidEmote state) const; - String getHeadFromIdentity() const; - String getBodyFromIdentity() const; - String getFacialEmotesFromIdentity() const; - String getHairFromIdentity() const; - String getFacialHairFromIdentity() const; - String getFacialMaskFromIdentity() const; - String getBackArmFromIdentity() const; - String getFrontArmFromIdentity() const; - String getVaporTrailFrameset() const; - Directives getBodyDirectives() const; Directives getHairDirectives() const; Directives getEmoteDirectives() const; From 2ccc2ac48767059df021784cb17293b969e6290a Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Wed, 1 Jan 2025 19:43:56 +1100 Subject: [PATCH 164/181] Update StarClientCommandProcessor.cpp [skip ci] --- source/frontend/StarClientCommandProcessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/frontend/StarClientCommandProcessor.cpp b/source/frontend/StarClientCommandProcessor.cpp index 78e1ee9..00a6c37 100644 --- a/source/frontend/StarClientCommandProcessor.cpp +++ b/source/frontend/StarClientCommandProcessor.cpp @@ -587,7 +587,7 @@ String ClientCommandProcessor::render(String const& path) { if (!File::isDirectory(outputDirectory)) File::makeDirectory(outputDirectory); image->writePng(File::open(outputPath, IOMode::Write | IOMode::Truncate)); - return strf("Saved {}x{} image to render.png", image->width(), image->height()); + return strf("Saved {}x{} image to {}.png", image->width(), image->height(), outputName); } From aaa1587f0c27572a243c26e449e62a85668df330 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Wed, 1 Jan 2025 22:46:37 +1100 Subject: [PATCH 165/181] Update StarPlayer.cpp [skip ci] --- source/game/StarPlayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/game/StarPlayer.cpp b/source/game/StarPlayer.cpp index 48368ec..c094bbb 100644 --- a/source/game/StarPlayer.cpp +++ b/source/game/StarPlayer.cpp @@ -1086,7 +1086,7 @@ void Player::update(float dt, uint64_t) { } if (calculateHeadRotation) { // master or not an OpenStarbound player float headRotation = 0.f; - if (m_humanoid->primaryHandHoldingItem() || m_humanoid->altHandHoldingItem()) { + if (m_humanoid->primaryHandHoldingItem() || m_humanoid->altHandHoldingItem() || m_humanoid->dance()) { auto primary = m_tools->primaryHandItem(); auto alt = m_tools->altHandItem(); String const disableFlag = "disableHeadRotation"; From bbc167de0f1b8c01ddf4caba30408f71999b2960 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 2 Jan 2025 16:07:34 +1100 Subject: [PATCH 166/181] fix ArmorWearer sync flag not being set for two slots no idea how I missed that [skip ci] --- source/game/StarArmorWearer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/game/StarArmorWearer.cpp b/source/game/StarArmorWearer.cpp index 4acce5f..89bebe3 100644 --- a/source/game/StarArmorWearer.cpp +++ b/source/game/StarArmorWearer.cpp @@ -350,11 +350,11 @@ void ArmorWearer::netElementsNeedLoad(bool) { m_backNeedsSync |= itemDatabase->loadItem(m_backCosmeticItemDataNetState.get(), m_backCosmeticItem); if (m_headItemDataNetState.pullUpdated()) - m_headNeedsSync |= !itemDatabase->loadItem(m_headItemDataNetState.get(), m_headItem); + m_headNeedsSync |= itemDatabase->loadItem(m_headItemDataNetState.get(), m_headItem); if (m_chestItemDataNetState.pullUpdated()) m_chestNeedsSync |= itemDatabase->loadItem(m_chestItemDataNetState.get(), m_chestItem); if (m_legsItemDataNetState.pullUpdated()) - m_legsNeedsSync |= !itemDatabase->loadItem(m_legsItemDataNetState.get(), m_legsItem); + m_legsNeedsSync |= itemDatabase->loadItem(m_legsItemDataNetState.get(), m_legsItem); if (m_backItemDataNetState.pullUpdated()) m_backNeedsSync |= itemDatabase->loadItem(m_backItemDataNetState.get(), m_backItem); } From 41f0b9001f60c59691ec04d937e6a9ef424794f1 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 2 Jan 2025 21:05:05 +1100 Subject: [PATCH 167/181] Update build.yml --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f263aa1..8987cd6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,7 +28,7 @@ jobs: build_windows: name: Build OpenStarbound Windows x64 runs-on: windows-latest - if: ${{ (github.event_name == 'workflow_dispatch') && (inputs.windows == true) }} + if: ${{ (github.event_name != 'workflow_dispatch') || (inputs.windows == true) }} steps: - name: Checkout uses: actions/checkout@v4 @@ -180,7 +180,7 @@ jobs: build-mac-intel: name: Build OpenStarbound macOS x86_64 runs-on: macos-13 - if: ${{ (github.event_name == 'workflow_dispatch') && (inputs.macOS == true) }} + if: ${{ (github.event_name != 'workflow_dispatch') || (inputs.macOS == true) }} steps: - uses: actions/checkout@v4 with: @@ -222,7 +222,7 @@ jobs: build-mac-arm: name: Build OpenStarbound macOS arm64 runs-on: macos-14 - if: ${{ (github.event_name == 'workflow_dispatch') && (inputs.macOS == true) }} + if: ${{ (github.event_name != 'workflow_dispatch') || (inputs.macOS == true) }} steps: - uses: actions/checkout@v4 with: From 9bc12f5f97f6774e6eeeb3ef577e026cc8d03357 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sun, 5 Jan 2025 15:16:15 +1100 Subject: [PATCH 168/181] Lua 5.3.6 --- source/extern/lauxlib.h | 14 +- source/extern/lua.h | 9 +- source/extern/lua/lapi.c | 182 +++++---- source/extern/lua/lapi.h | 2 +- source/extern/lua/lauxlib.c | 168 ++++++--- source/extern/lua/lbaselib.c | 52 +-- source/extern/lua/lbitlib.c | 51 +-- source/extern/lua/lcode.c | 704 +++++++++++++++++++++++------------ source/extern/lua/lcode.h | 5 +- source/extern/lua/lcorolib.c | 4 +- source/extern/lua/lctype.c | 2 +- source/extern/lua/lctype.h | 2 +- source/extern/lua/ldblib.c | 6 +- source/extern/lua/ldebug.c | 75 ++-- source/extern/lua/ldebug.h | 2 +- source/extern/lua/ldo.c | 337 ++++++++++------- source/extern/lua/ldo.h | 26 +- source/extern/lua/ldump.c | 4 +- source/extern/lua/lfunc.c | 2 +- source/extern/lua/lfunc.h | 2 +- source/extern/lua/lgc.c | 70 ++-- source/extern/lua/lgc.h | 41 +- source/extern/lua/linit.c | 6 +- source/extern/lua/liolib.c | 72 ++-- source/extern/lua/llex.c | 70 +--- source/extern/lua/llex.h | 3 +- source/extern/lua/llimits.h | 34 +- source/extern/lua/lmathlib.c | 21 +- source/extern/lua/lmem.c | 2 +- source/extern/lua/lmem.h | 2 +- source/extern/lua/loadlib.c | 171 ++++----- source/extern/lua/lobject.c | 119 ++++-- source/extern/lua/lobject.h | 84 ++--- source/extern/lua/lopcodes.c | 2 +- source/extern/lua/lopcodes.h | 4 +- source/extern/lua/loslib.c | 165 ++++---- source/extern/lua/lparser.c | 60 +-- source/extern/lua/lparser.h | 53 ++- source/extern/lua/lprefix.h | 2 +- source/extern/lua/lstate.c | 29 +- source/extern/lua/lstate.h | 52 ++- source/extern/lua/lstring.c | 76 ++-- source/extern/lua/lstring.h | 4 +- source/extern/lua/lstrlib.c | 268 ++++++++----- source/extern/lua/ltable.c | 155 +++++--- source/extern/lua/ltable.h | 21 +- source/extern/lua/ltablib.c | 377 ++++++++++++------- source/extern/lua/ltm.c | 37 +- source/extern/lua/ltm.h | 5 +- source/extern/lua/lundump.c | 40 +- source/extern/lua/lundump.h | 5 +- source/extern/lua/lutf8lib.c | 6 +- source/extern/lua/lvm.c | 262 +++++++------ source/extern/lua/lvm.h | 55 ++- source/extern/lua/lzio.c | 12 +- source/extern/lua/lzio.h | 3 +- source/extern/luaconf.h | 98 +++-- source/extern/lualib.h | 5 +- 58 files changed, 2574 insertions(+), 1566 deletions(-) diff --git a/source/extern/lauxlib.h b/source/extern/lauxlib.h index 0bac246..9857d3a 100644 --- a/source/extern/lauxlib.h +++ b/source/extern/lauxlib.h @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.h,v 1.128 2014/10/29 16:11:17 roberto Exp $ +** $Id: lauxlib.h,v 1.131.1.1 2017/04/19 17:20:42 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -16,10 +16,18 @@ -/* extra error code for 'luaL_load' */ +/* extra error code for 'luaL_loadfilex' */ #define LUA_ERRFILE (LUA_ERRERR+1) +/* key, in the registry, for table of loaded modules */ +#define LUA_LOADED_TABLE "_LOADED" + + +/* key, in the registry, for table of preloaded loaders */ +#define LUA_PRELOAD_TABLE "_PRELOAD" + + typedef struct luaL_Reg { const char *name; lua_CFunction func; @@ -65,7 +73,7 @@ LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def, LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); LUALIB_API int (luaL_execresult) (lua_State *L, int stat); -/* pre-defined references */ +/* predefined references */ #define LUA_NOREF (-2) #define LUA_REFNIL (-1) diff --git a/source/extern/lua.h b/source/extern/lua.h index 1c2b95a..9394c5e 100644 --- a/source/extern/lua.h +++ b/source/extern/lua.h @@ -1,5 +1,4 @@ /* -** $Id: lua.h,v 1.328 2015/06/03 13:03:38 roberto Exp $ ** Lua - A Scripting Language ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) ** See Copyright Notice at the end of this file @@ -19,11 +18,11 @@ #define LUA_VERSION_MAJOR "5" #define LUA_VERSION_MINOR "3" #define LUA_VERSION_NUM 503 -#define LUA_VERSION_RELEASE "1" +#define LUA_VERSION_RELEASE "6" #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE -#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2015 Lua.org, PUC-Rio" +#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2020 Lua.org, PUC-Rio" #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" @@ -361,7 +360,7 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); #define lua_pushliteral(L, s) lua_pushstring(L, "" s) #define lua_pushglobaltable(L) \ - lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS) + ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)) #define lua_tostring(L,i) lua_tolstring(L, (i), NULL) @@ -460,7 +459,7 @@ struct lua_Debug { /****************************************************************************** -* Copyright (C) 1994-2015 Lua.org, PUC-Rio. +* Copyright (C) 1994-2020 Lua.org, PUC-Rio. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the diff --git a/source/extern/lua/lapi.c b/source/extern/lua/lapi.c index fea9eb2..711895b 100644 --- a/source/extern/lua/lapi.c +++ b/source/extern/lua/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.249 2015/04/06 12:23:48 roberto Exp $ +** $Id: lapi.c,v 2.259.1.2 2017/12/06 18:35:12 roberto Exp $ ** Lua API ** See Copyright Notice in lua.h */ @@ -121,11 +121,11 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { lua_lock(to); api_checknelems(from, n); api_check(from, G(from) == G(to), "moving among independent states"); - api_check(from, to->ci->top - to->top >= n, "not enough elements to move"); + api_check(from, to->ci->top - to->top >= n, "stack overflow"); from->top -= n; for (i = 0; i < n; i++) { setobj2s(to, to->top, from->top + i); - api_incr_top(to); + to->top++; /* stack already checked by previous 'api_check' */ } lua_unlock(to); } @@ -378,9 +378,9 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { return NULL; } lua_lock(L); /* 'luaO_tostring' may create a new string */ + luaO_tostring(L, o); luaC_checkGC(L); o = index2addr(L, idx); /* previous call may reallocate the stack */ - luaO_tostring(L, o); lua_unlock(L); } if (len != NULL) @@ -471,13 +471,18 @@ LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { } +/* +** Pushes on the stack a string with given length. Avoid using 's' when +** 'len' == 0 (as 's' can be NULL in that case), due to later use of +** 'memcmp' and 'memcpy'. +*/ LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) { TString *ts; lua_lock(L); - luaC_checkGC(L); - ts = luaS_newlstr(L, s, len); + ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len); setsvalue2s(L, L->top, ts); api_incr_top(L); + luaC_checkGC(L); lua_unlock(L); return getstr(ts); } @@ -489,12 +494,12 @@ LUA_API const char *lua_pushstring (lua_State *L, const char *s) { setnilvalue(L->top); else { TString *ts; - luaC_checkGC(L); ts = luaS_new(L, s); setsvalue2s(L, L->top, ts); s = getstr(ts); /* internal copy's address */ } api_incr_top(L); + luaC_checkGC(L); lua_unlock(L); return s; } @@ -504,8 +509,8 @@ LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, va_list argp) { const char *ret; lua_lock(L); - luaC_checkGC(L); ret = luaO_pushvfstring(L, fmt, argp); + luaC_checkGC(L); lua_unlock(L); return ret; } @@ -515,10 +520,10 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { const char *ret; va_list argp; lua_lock(L); - luaC_checkGC(L); va_start(argp, fmt); ret = luaO_pushvfstring(L, fmt, argp); va_end(argp); + luaC_checkGC(L); lua_unlock(L); return ret; } @@ -528,12 +533,12 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { lua_lock(L); if (n == 0) { setfvalue(L->top, fn); + api_incr_top(L); } else { CClosure *cl; api_checknelems(L, n); api_check(L, n <= MAXUPVAL, "upvalue index too large"); - luaC_checkGC(L); cl = luaF_newCclosure(L, n); cl->f = fn; L->top -= n; @@ -542,8 +547,9 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { /* does not need barrier because closure is white */ } setclCvalue(L, L->top, cl); + api_incr_top(L); + luaC_checkGC(L); } - api_incr_top(L); lua_unlock(L); } @@ -579,19 +585,30 @@ LUA_API int lua_pushthread (lua_State *L) { */ -LUA_API int lua_getglobal (lua_State *L, const char *name) { - Table *reg = hvalue(&G(L)->l_registry); - const TValue *gt; /* global table */ - lua_lock(L); - gt = luaH_getint(reg, LUA_RIDX_GLOBALS); - setsvalue2s(L, L->top, luaS_new(L, name)); - api_incr_top(L); - luaV_gettable(L, gt, L->top - 1, L->top - 1); +static int auxgetstr (lua_State *L, const TValue *t, const char *k) { + const TValue *slot; + TString *str = luaS_new(L, k); + if (luaV_fastget(L, t, str, slot, luaH_getstr)) { + setobj2s(L, L->top, slot); + api_incr_top(L); + } + else { + setsvalue2s(L, L->top, str); + api_incr_top(L); + luaV_finishget(L, t, L->top - 1, L->top - 1, slot); + } lua_unlock(L); return ttnov(L->top - 1); } +LUA_API int lua_getglobal (lua_State *L, const char *name) { + Table *reg = hvalue(&G(L)->l_registry); + lua_lock(L); + return auxgetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name); +} + + LUA_API int lua_gettable (lua_State *L, int idx) { StkId t; lua_lock(L); @@ -603,24 +620,25 @@ LUA_API int lua_gettable (lua_State *L, int idx) { LUA_API int lua_getfield (lua_State *L, int idx, const char *k) { - StkId t; lua_lock(L); - t = index2addr(L, idx); - setsvalue2s(L, L->top, luaS_new(L, k)); - api_incr_top(L); - luaV_gettable(L, t, L->top - 1, L->top - 1); - lua_unlock(L); - return ttnov(L->top - 1); + return auxgetstr(L, index2addr(L, idx), k); } LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) { StkId t; + const TValue *slot; lua_lock(L); t = index2addr(L, idx); - setivalue(L->top, n); - api_incr_top(L); - luaV_gettable(L, t, L->top - 1, L->top - 1); + if (luaV_fastget(L, t, n, slot, luaH_getint)) { + setobj2s(L, L->top, slot); + api_incr_top(L); + } + else { + setivalue(L->top, n); + api_incr_top(L); + luaV_finishget(L, t, L->top - 1, L->top - 1, slot); + } lua_unlock(L); return ttnov(L->top - 1); } @@ -666,12 +684,12 @@ LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) { LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { Table *t; lua_lock(L); - luaC_checkGC(L); t = luaH_new(L); sethvalue(L, L->top, t); api_incr_top(L); if (narray > 0 || nrec > 0) luaH_resize(L, t, narray, nrec); + luaC_checkGC(L); lua_unlock(L); } @@ -719,18 +737,29 @@ LUA_API int lua_getuservalue (lua_State *L, int idx) { ** set functions (stack -> Lua) */ +/* +** t[k] = value at the top of the stack (where 'k' is a string) +*/ +static void auxsetstr (lua_State *L, const TValue *t, const char *k) { + const TValue *slot; + TString *str = luaS_new(L, k); + api_checknelems(L, 1); + if (luaV_fastset(L, t, str, slot, luaH_getstr, L->top - 1)) + L->top--; /* pop value */ + else { + setsvalue2s(L, L->top, str); /* push 'str' (to make it a TValue) */ + api_incr_top(L); + luaV_finishset(L, t, L->top - 1, L->top - 2, slot); + L->top -= 2; /* pop value and key */ + } + lua_unlock(L); /* lock done by caller */ +} + LUA_API void lua_setglobal (lua_State *L, const char *name) { Table *reg = hvalue(&G(L)->l_registry); - const TValue *gt; /* global table */ - lua_lock(L); - api_checknelems(L, 1); - gt = luaH_getint(reg, LUA_RIDX_GLOBALS); - setsvalue2s(L, L->top, luaS_new(L, name)); - api_incr_top(L); - luaV_settable(L, gt, L->top - 1, L->top - 2); - L->top -= 2; /* pop value and key */ - lua_unlock(L); + lua_lock(L); /* unlock done in 'auxsetstr' */ + auxsetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name); } @@ -746,42 +775,40 @@ LUA_API void lua_settable (lua_State *L, int idx) { LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { - StkId t; - lua_lock(L); - api_checknelems(L, 1); - t = index2addr(L, idx); - setsvalue2s(L, L->top, luaS_new(L, k)); - api_incr_top(L); - luaV_settable(L, t, L->top - 1, L->top - 2); - L->top -= 2; /* pop value and key */ - lua_unlock(L); + lua_lock(L); /* unlock done in 'auxsetstr' */ + auxsetstr(L, index2addr(L, idx), k); } LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) { StkId t; + const TValue *slot; lua_lock(L); api_checknelems(L, 1); t = index2addr(L, idx); - setivalue(L->top, n); - api_incr_top(L); - luaV_settable(L, t, L->top - 1, L->top - 2); - L->top -= 2; /* pop value and key */ + if (luaV_fastset(L, t, n, slot, luaH_getint, L->top - 1)) + L->top--; /* pop value */ + else { + setivalue(L->top, n); + api_incr_top(L); + luaV_finishset(L, t, L->top - 1, L->top - 2, slot); + L->top -= 2; /* pop value and key */ + } lua_unlock(L); } LUA_API void lua_rawset (lua_State *L, int idx) { StkId o; - Table *t; + TValue *slot; lua_lock(L); api_checknelems(L, 2); o = index2addr(L, idx); api_check(L, ttistable(o), "table expected"); - t = hvalue(o); - setobj2t(L, luaH_set(L, t, L->top-2), L->top-1); - invalidateTMcache(t); - luaC_barrierback(L, t, L->top-1); + slot = luaH_set(L, hvalue(o), L->top - 2); + setobj2t(L, slot, L->top - 1); + invalidateTMcache(hvalue(o)); + luaC_barrierback(L, hvalue(o), L->top-1); L->top -= 2; lua_unlock(L); } @@ -789,14 +816,12 @@ LUA_API void lua_rawset (lua_State *L, int idx) { LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) { StkId o; - Table *t; lua_lock(L); api_checknelems(L, 1); o = index2addr(L, idx); api_check(L, ttistable(o), "table expected"); - t = hvalue(o); - luaH_setint(L, t, n, L->top - 1); - luaC_barrierback(L, t, L->top-1); + luaH_setint(L, hvalue(o), n, L->top - 1); + luaC_barrierback(L, hvalue(o), L->top-1); L->top--; lua_unlock(L); } @@ -804,16 +829,15 @@ LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) { LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { StkId o; - Table *t; - TValue k; + TValue k, *slot; lua_lock(L); api_checknelems(L, 1); o = index2addr(L, idx); api_check(L, ttistable(o), "table expected"); - t = hvalue(o); setpvalue(&k, cast(void *, p)); - setobj2t(L, luaH_set(L, t, &k), L->top - 1); - luaC_barrierback(L, t, L->top - 1); + slot = luaH_set(L, hvalue(o), &k); + setobj2t(L, slot, L->top - 1); + luaC_barrierback(L, hvalue(o), L->top - 1); L->top--; lua_unlock(L); } @@ -895,10 +919,10 @@ LUA_API void lua_callk (lua_State *L, int nargs, int nresults, if (k != NULL && L->nny == 0) { /* need to prepare continuation? */ L->ci->u.c.k = k; /* save continuation */ L->ci->u.c.ctx = ctx; /* save context */ - luaD_call(L, func, nresults, 1); /* do the call */ + luaD_call(L, func, nresults); /* do the call */ } else /* no continuation or no yieldable */ - luaD_call(L, func, nresults, 0); /* just do the call */ + luaD_callnoyield(L, func, nresults); /* just do the call */ adjustresults(L, nresults); lua_unlock(L); } @@ -916,7 +940,7 @@ struct CallS { /* data to 'f_call' */ static void f_call (lua_State *L, void *ud) { struct CallS *c = cast(struct CallS *, ud); - luaD_call(L, c->func, c->nresults, 0); + luaD_callnoyield(L, c->func, c->nresults); } @@ -954,7 +978,7 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, L->errfunc = func; setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */ ci->callstatus |= CIST_YPCALL; /* function can do error recovery */ - luaD_call(L, c.func, nresults, 1); /* do the call */ + luaD_call(L, c.func, nresults); /* do the call */ ci->callstatus &= ~CIST_YPCALL; L->errfunc = ci->u.c.old_errfunc; status = LUA_OK; /* if it is here, there were no errors */ @@ -1043,7 +1067,7 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { } case LUA_GCSTEP: { l_mem debt = 1; /* =1 to signal that it did an actual step */ - int oldrunning = g->gcrunning; + lu_byte oldrunning = g->gcrunning; g->gcrunning = 1; /* allow GC to run */ if (data == 0) { luaE_setdebt(g, -GCSTEPSIZE); /* to do a "small" step */ @@ -1117,7 +1141,6 @@ LUA_API void lua_concat (lua_State *L, int n) { lua_lock(L); api_checknelems(L, n); if (n >= 2) { - luaC_checkGC(L); luaV_concat(L, n); } else if (n == 0) { /* push empty string */ @@ -1125,6 +1148,7 @@ LUA_API void lua_concat (lua_State *L, int n) { api_incr_top(L); } /* else n == 1; nothing to do */ + luaC_checkGC(L); lua_unlock(L); } @@ -1160,10 +1184,10 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { LUA_API void *lua_newuserdata (lua_State *L, size_t size) { Udata *u; lua_lock(L); - luaC_checkGC(L); u = luaS_newudata(L, size); setuvalue(L, L->top, u); api_incr_top(L); + luaC_checkGC(L); lua_unlock(L); return getudatamem(u); } @@ -1230,13 +1254,12 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { } -static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { +static UpVal **getupvalref (lua_State *L, int fidx, int n) { LClosure *f; StkId fi = index2addr(L, fidx); api_check(L, ttisLclosure(fi), "Lua function expected"); f = clLvalue(fi); api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); - if (pf) *pf = f; return &f->upvals[n - 1]; /* get its upvalue pointer */ } @@ -1245,7 +1268,7 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { StkId fi = index2addr(L, fidx); switch (ttype(fi)) { case LUA_TLCL: { /* lua closure */ - return *getupvalref(L, fidx, n, NULL); + return *getupvalref(L, fidx, n); } case LUA_TCCL: { /* C closure */ CClosure *f = clCvalue(fi); @@ -1262,9 +1285,10 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, int fidx2, int n2) { - LClosure *f1; - UpVal **up1 = getupvalref(L, fidx1, n1, &f1); - UpVal **up2 = getupvalref(L, fidx2, n2, NULL); + UpVal **up1 = getupvalref(L, fidx1, n1); + UpVal **up2 = getupvalref(L, fidx2, n2); + if (*up1 == *up2) + return; luaC_upvdeccount(L, *up1); *up1 = *up2; (*up1)->refcount++; diff --git a/source/extern/lua/lapi.h b/source/extern/lua/lapi.h index 6d36dee..8e16ad5 100644 --- a/source/extern/lua/lapi.h +++ b/source/extern/lua/lapi.h @@ -1,5 +1,5 @@ /* -** $Id: lapi.h,v 2.9 2015/03/06 19:49:50 roberto Exp $ +** $Id: lapi.h,v 2.9.1.1 2017/04/19 17:20:42 roberto Exp $ ** Auxiliary functions from Lua API ** See Copyright Notice in lua.h */ diff --git a/source/extern/lua/lauxlib.c b/source/extern/lua/lauxlib.c index b8bace7..ac68bd3 100644 --- a/source/extern/lua/lauxlib.c +++ b/source/extern/lua/lauxlib.c @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.c,v 1.280 2015/02/03 17:38:24 roberto Exp $ +** $Id: lauxlib.c,v 1.289.1.1 2017/04/19 17:20:42 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -17,7 +17,8 @@ #include -/* This file uses only the official API of Lua. +/* +** This file uses only the official API of Lua. ** Any function declared here could be written as an application function. */ @@ -33,8 +34,8 @@ */ -#define LEVELS1 12 /* size of the first part of the stack */ -#define LEVELS2 10 /* size of the second part of the stack */ +#define LEVELS1 10 /* size of the first part of the stack */ +#define LEVELS2 11 /* size of the second part of the stack */ @@ -68,12 +69,11 @@ static int findfield (lua_State *L, int objidx, int level) { /* ** Search for a name for a function in all loaded modules -** (registry._LOADED). */ static int pushglobalfuncname (lua_State *L, lua_Debug *ar) { int top = lua_gettop(L); lua_getinfo(L, "f", ar); /* push function */ - lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); if (findfield(L, top + 1, 2)) { const char *name = lua_tostring(L, -1); if (strncmp(name, "_G.", 3) == 0) { /* name start with '_G.'? */ @@ -107,7 +107,7 @@ static void pushfuncname (lua_State *L, lua_Debug *ar) { } -static int countlevels (lua_State *L) { +static int lastlevel (lua_State *L) { lua_Debug ar; int li = 1, le = 1; /* find an upper bound */ @@ -126,14 +126,16 @@ LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg, int level) { lua_Debug ar; int top = lua_gettop(L); - int numlevels = countlevels(L1); - int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0; - if (msg) lua_pushfstring(L, "%s\n", msg); + int last = lastlevel(L1); + int n1 = (last - level > LEVELS1 + LEVELS2) ? LEVELS1 : -1; + if (msg) + lua_pushfstring(L, "%s\n", msg); + luaL_checkstack(L, 10, NULL); lua_pushliteral(L, "stack traceback:"); while (lua_getstack(L1, level++, &ar)) { - if (level == mark) { /* too many levels? */ + if (n1-- == 0) { /* too many levels? */ lua_pushliteral(L, "\n\t..."); /* add a '...' */ - level = numlevels - LEVELS2; /* and skip to last ones */ + level = last - LEVELS2 + 1; /* and skip to last ones */ } else { lua_getinfo(L1, "Slnt", &ar); @@ -196,6 +198,10 @@ static void tag_error (lua_State *L, int arg, int tag) { } +/* +** The use of 'lua_pushfstring' ensures this function does not +** need reserved stack space when called. +*/ LUALIB_API void luaL_where (lua_State *L, int level) { lua_Debug ar; if (lua_getstack(L, level, &ar)) { /* check function at level */ @@ -205,10 +211,15 @@ LUALIB_API void luaL_where (lua_State *L, int level) { return; } } - lua_pushliteral(L, ""); /* else, no information available... */ + lua_pushfstring(L, ""); /* else, no information available... */ } +/* +** Again, the use of 'lua_pushvfstring' ensures this function does +** not need reserved stack space when called. (At worst, it generates +** an error with "stack overflow" instead of the given message.) +*/ LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { va_list argp; va_start(argp, fmt); @@ -289,7 +300,7 @@ LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { if (luaL_getmetatable(L, tname) != LUA_TNIL) /* name already in use? */ return 0; /* leave previous value on top, but return 0 */ lua_pop(L, 1); - lua_newtable(L); /* create metatable */ + lua_createtable(L, 0, 2); /* create metatable */ lua_pushstring(L, tname); lua_setfield(L, -2, "__name"); /* metatable.__name = tname */ lua_pushvalue(L, -1); @@ -347,10 +358,15 @@ LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def, } +/* +** Ensures the stack has at least 'space' extra slots, raising an error +** if it cannot fulfill the request. (The error handling needs a few +** extra slots to format the error message. In case of an error without +** this extra space, Lua will generate the same 'stack overflow' error, +** but without 'msg'.) +*/ LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) { - /* keep some extra space to run error routines, if needed */ - const int extra = LUA_MINSTACK; - if (!lua_checkstack(L, space + extra)) { + if (!lua_checkstack(L, space)) { if (msg) luaL_error(L, "stack overflow (%s)", msg); else @@ -435,6 +451,47 @@ LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int arg, ** ======================================================= */ +/* userdata to box arbitrary data */ +typedef struct UBox { + void *box; + size_t bsize; +} UBox; + + +static void *resizebox (lua_State *L, int idx, size_t newsize) { + void *ud; + lua_Alloc allocf = lua_getallocf(L, &ud); + UBox *box = (UBox *)lua_touserdata(L, idx); + void *temp = allocf(ud, box->box, box->bsize, newsize); + if (temp == NULL && newsize > 0) { /* allocation error? */ + resizebox(L, idx, 0); /* free buffer */ + luaL_error(L, "not enough memory for buffer allocation"); + } + box->box = temp; + box->bsize = newsize; + return temp; +} + + +static int boxgc (lua_State *L) { + resizebox(L, 1, 0); + return 0; +} + + +static void *newbox (lua_State *L, size_t newsize) { + UBox *box = (UBox *)lua_newuserdata(L, sizeof(UBox)); + box->box = NULL; + box->bsize = 0; + if (luaL_newmetatable(L, "LUABOX")) { /* creating metatable? */ + lua_pushcfunction(L, boxgc); + lua_setfield(L, -2, "__gc"); /* metatable.__gc = boxgc */ + } + lua_setmetatable(L, -2); + return resizebox(L, -1, newsize); +} + + /* ** check whether buffer is using a userdata on the stack as a temporary ** buffer @@ -455,11 +512,12 @@ LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { if (newsize < B->n || newsize - B->n < sz) luaL_error(L, "buffer too large"); /* create larger buffer */ - newbuff = (char *)lua_newuserdata(L, newsize * sizeof(char)); - /* move content to new buffer */ - memcpy(newbuff, B->b, B->n * sizeof(char)); if (buffonstack(B)) - lua_remove(L, -2); /* remove old buffer */ + newbuff = (char *)resizebox(L, -1, newsize); + else { /* no buffer yet */ + newbuff = (char *)newbox(L, newsize); + memcpy(newbuff, B->b, B->n * sizeof(char)); /* copy original content */ + } B->b = newbuff; B->size = newsize; } @@ -468,9 +526,11 @@ LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { - char *b = luaL_prepbuffsize(B, l); - memcpy(b, s, l * sizeof(char)); - luaL_addsize(B, l); + if (l > 0) { /* avoid 'memcpy' when 's' can be NULL */ + char *b = luaL_prepbuffsize(B, l); + memcpy(b, s, l * sizeof(char)); + luaL_addsize(B, l); + } } @@ -482,8 +542,10 @@ LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { LUALIB_API void luaL_pushresult (luaL_Buffer *B) { lua_State *L = B->L; lua_pushlstring(L, B->b, B->n); - if (buffonstack(B)) - lua_remove(L, -2); /* remove old buffer */ + if (buffonstack(B)) { + resizebox(L, -2, 0); /* delete old buffer */ + lua_remove(L, -2); /* remove its header from the stack */ + } } @@ -605,7 +667,7 @@ static int errfile (lua_State *L, const char *what, int fnameindex) { static int skipBOM (LoadF *lf) { - const char *p = "\xEF\xBB\xBF"; /* Utf8 BOM mark */ + const char *p = "\xEF\xBB\xBF"; /* UTF-8 BOM mark */ int c; lf->n = 0; do { @@ -630,7 +692,7 @@ static int skipcomment (LoadF *lf, int *cp) { if (c == '#') { /* first line is a comment (Unix exec. file)? */ do { /* skip first line */ c = getc(lf->f); - } while (c != EOF && c != '\n') ; + } while (c != EOF && c != '\n'); *cp = getc(lf->f); /* skip end-of-line, if present */ return 1; /* there was a comment */ } @@ -746,13 +808,17 @@ LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) { LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { - if (!luaL_callmeta(L, idx, "__tostring")) { /* no metafield? */ + if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */ + if (!lua_isstring(L, -1)) + luaL_error(L, "'__tostring' must return a string"); + } + else { switch (lua_type(L, idx)) { case LUA_TNUMBER: { if (lua_isinteger(L, idx)) - lua_pushfstring(L, "%I", lua_tointeger(L, idx)); + lua_pushfstring(L, "%I", (LUAI_UACINT)lua_tointeger(L, idx)); else - lua_pushfstring(L, "%f", lua_tonumber(L, idx)); + lua_pushfstring(L, "%f", (LUAI_UACNUMBER)lua_tonumber(L, idx)); break; } case LUA_TSTRING: @@ -764,10 +830,15 @@ LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { case LUA_TNIL: lua_pushliteral(L, "nil"); break; - default: - lua_pushfstring(L, "%s: %p", luaL_typename(L, idx), - lua_topointer(L, idx)); + default: { + int tt = luaL_getmetafield(L, idx, "__name"); /* try name */ + const char *kind = (tt == LUA_TSTRING) ? lua_tostring(L, -1) : + luaL_typename(L, idx); + lua_pushfstring(L, "%s: %p", kind, lua_topointer(L, idx)); + if (tt != LUA_TNIL) + lua_remove(L, -2); /* remove '__name' */ break; + } } } return lua_tolstring(L, -1, len); @@ -819,23 +890,23 @@ static int libsize (const luaL_Reg *l) { /* ** Find or create a module table with a given name. The function -** first looks at the _LOADED table and, if that fails, try a +** first looks at the LOADED table and, if that fails, try a ** global variable with that name. In any case, leaves on the stack ** the module table. */ LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname, int sizehint) { - luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */ - if (lua_getfield(L, -1, modname) != LUA_TTABLE) { /* no _LOADED[modname]? */ + luaL_findtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE, 1); + if (lua_getfield(L, -1, modname) != LUA_TTABLE) { /* no LOADED[modname]? */ lua_pop(L, 1); /* remove previous result */ /* try global variable (and create one if it does not exist) */ lua_pushglobaltable(L); if (luaL_findtable(L, 0, modname, sizehint) != NULL) luaL_error(L, "name conflict for module '%s'", modname); lua_pushvalue(L, -1); - lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */ + lua_setfield(L, -3, modname); /* LOADED[modname] = new table */ } - lua_remove(L, -2); /* remove _LOADED table */ + lua_remove(L, -2); /* remove LOADED table */ } @@ -899,17 +970,17 @@ LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) { */ LUALIB_API void luaL_requiref (lua_State *L, const char *modname, lua_CFunction openf, int glb) { - luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); - lua_getfield(L, -1, modname); /* _LOADED[modname] */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + lua_getfield(L, -1, modname); /* LOADED[modname] */ if (!lua_toboolean(L, -1)) { /* package not already loaded? */ lua_pop(L, 1); /* remove field */ lua_pushcfunction(L, openf); lua_pushstring(L, modname); /* argument to open function */ lua_call(L, 1, 1); /* call 'openf' to open module */ lua_pushvalue(L, -1); /* make copy of module (call result) */ - lua_setfield(L, -3, modname); /* _LOADED[modname] = module */ + lua_setfield(L, -3, modname); /* LOADED[modname] = module */ } - lua_remove(L, -2); /* remove _LOADED table */ + lua_remove(L, -2); /* remove LOADED table */ if (glb) { lua_pushvalue(L, -1); /* copy of module */ lua_setglobal(L, modname); /* _G[modname] = module */ @@ -940,8 +1011,13 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { free(ptr); return NULL; } - else - return realloc(ptr, nsize); + else { /* cannot fail when shrinking a block */ + void *newptr = realloc(ptr, nsize); + if (newptr == NULL && ptr != NULL && nsize <= osize) + return ptr; /* keep the original block */ + else /* no fail or not shrinking */ + return newptr; /* use the new block */ + } } @@ -967,6 +1043,6 @@ LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) { luaL_error(L, "multiple Lua VMs detected"); else if (*v != ver) luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", - ver, *v); + (LUAI_UACNUMBER)ver, (LUAI_UACNUMBER)*v); } diff --git a/source/extern/lua/lbaselib.c b/source/extern/lua/lbaselib.c index 9a15124..6460e4f 100644 --- a/source/extern/lua/lbaselib.c +++ b/source/extern/lua/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.310 2015/03/28 19:14:47 roberto Exp $ +** $Id: lbaselib.c,v 1.314.1.1 2017/04/19 17:39:34 roberto Exp $ ** Basic library ** See Copyright Notice in lua.h */ @@ -86,8 +86,8 @@ static int luaB_tonumber (lua_State *L) { const char *s; lua_Integer n = 0; /* to avoid warnings */ lua_Integer base = luaL_checkinteger(L, 2); - luaL_checktype(L, 1, LUA_TSTRING); /* before 'luaL_checklstring'! */ - s = luaL_checklstring(L, 1, &l); + luaL_checktype(L, 1, LUA_TSTRING); /* no numbers as strings */ + s = lua_tolstring(L, 1, &l); luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); if (b_str2int(s, (int)base, &n) == s + l) { lua_pushinteger(L, n); @@ -102,8 +102,8 @@ static int luaB_tonumber (lua_State *L) { static int luaB_error (lua_State *L) { int level = (int)luaL_optinteger(L, 2, 1); lua_settop(L, 1); - if (lua_isstring(L, 1) && level > 0) { /* add extra information? */ - luaL_where(L, level); + if (lua_type(L, 1) == LUA_TSTRING && level > 0) { + luaL_where(L, level); /* add extra information */ lua_pushvalue(L, 1); lua_concat(L, 2); } @@ -198,20 +198,18 @@ static int luaB_collectgarbage (lua_State *L) { } -/* -** This function has all type names as upvalues, to maximize performance. -*/ static int luaB_type (lua_State *L) { - luaL_checkany(L, 1); - lua_pushvalue(L, lua_upvalueindex(lua_type(L, 1) + 1)); + int t = lua_type(L, 1); + luaL_argcheck(L, t != LUA_TNONE, 1, "value expected"); + lua_pushstring(L, lua_typename(L, t)); return 1; } static int pairsmeta (lua_State *L, const char *method, int iszero, lua_CFunction iter) { + luaL_checkany(L, 1); if (luaL_getmetafield(L, 1, method) == LUA_TNIL) { /* no metamethod? */ - luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */ lua_pushcfunction(L, iter); /* will return generator, */ lua_pushvalue(L, 1); /* state, */ if (iszero) lua_pushinteger(L, 0); /* and initial value */ @@ -243,18 +241,7 @@ static int luaB_pairs (lua_State *L) { /* -** Traversal function for 'ipairs' for raw tables -*/ -static int ipairsaux_raw (lua_State *L) { - lua_Integer i = luaL_checkinteger(L, 2) + 1; - luaL_checktype(L, 1, LUA_TTABLE); - lua_pushinteger(L, i); - return (lua_rawgeti(L, 1, i) == LUA_TNIL) ? 1 : 2; -} - - -/* -** Traversal function for 'ipairs' for tables with metamethods +** Traversal function for 'ipairs' */ static int ipairsaux (lua_State *L) { lua_Integer i = luaL_checkinteger(L, 2) + 1; @@ -264,18 +251,15 @@ static int ipairsaux (lua_State *L) { /* -** This function will use either 'ipairsaux' or 'ipairsaux_raw' to -** traverse a table, depending on whether the table has metamethods -** that can affect the traversal. +** 'ipairs' function. Returns 'ipairsaux', given "table", 0. +** (The given "table" may not be a table.) */ static int luaB_ipairs (lua_State *L) { - lua_CFunction iter = (luaL_getmetafield(L, 1, "__index") != LUA_TNIL) - ? ipairsaux : ipairsaux_raw; #if defined(LUA_COMPAT_IPAIRS) - return pairsmeta(L, "__ipairs", 1, iter); + return pairsmeta(L, "__ipairs", 1, ipairsaux); #else luaL_checkany(L, 1); - lua_pushcfunction(L, iter); /* iteration function */ + lua_pushcfunction(L, ipairsaux); /* iteration function */ lua_pushvalue(L, 1); /* state */ lua_pushinteger(L, 0); /* initial value */ return 3; @@ -490,9 +474,9 @@ static const luaL_Reg base_funcs[] = { {"setmetatable", luaB_setmetatable}, {"tonumber", luaB_tonumber}, {"tostring", luaB_tostring}, + {"type", luaB_type}, {"xpcall", luaB_xpcall}, /* placeholders */ - {"type", NULL}, {"_G", NULL}, {"_VERSION", NULL}, {NULL, NULL} @@ -500,7 +484,6 @@ static const luaL_Reg base_funcs[] = { LUAMOD_API int luaopen_base (lua_State *L) { - int i; /* open lib into global table */ lua_pushglobaltable(L); luaL_setfuncs(L, base_funcs, 0); @@ -510,11 +493,6 @@ LUAMOD_API int luaopen_base (lua_State *L) { /* set global _VERSION */ lua_pushliteral(L, LUA_VERSION); lua_setfield(L, -2, "_VERSION"); - /* set function 'type' with proper upvalues */ - for (i = 0; i < LUA_NUMTAGS; i++) /* push all type names as upvalues */ - lua_pushstring(L, lua_typename(L, i)); - lua_pushcclosure(L, luaB_type, LUA_NUMTAGS); - lua_setfield(L, -2, "type"); return 1; } diff --git a/source/extern/lua/lbitlib.c b/source/extern/lua/lbitlib.c index 15d5f0c..4786c0d 100644 --- a/source/extern/lua/lbitlib.c +++ b/source/extern/lua/lbitlib.c @@ -1,5 +1,5 @@ /* -** $Id: lbitlib.c,v 1.28 2014/11/02 19:19:04 roberto Exp $ +** $Id: lbitlib.c,v 1.30.1.1 2017/04/19 17:20:42 roberto Exp $ ** Standard library for bitwise operations ** See Copyright Notice in lua.h */ @@ -19,6 +19,10 @@ #if defined(LUA_COMPAT_BITLIB) /* { */ +#define pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n)) +#define checkunsigned(L,i) ((lua_Unsigned)luaL_checkinteger(L,i)) + + /* number of bits to consider in a number */ #if !defined(LUA_NBITS) #define LUA_NBITS 32 @@ -46,14 +50,14 @@ static lua_Unsigned andaux (lua_State *L) { int i, n = lua_gettop(L); lua_Unsigned r = ~(lua_Unsigned)0; for (i = 1; i <= n; i++) - r &= luaL_checkunsigned(L, i); + r &= checkunsigned(L, i); return trim(r); } static int b_and (lua_State *L) { lua_Unsigned r = andaux(L); - lua_pushunsigned(L, r); + pushunsigned(L, r); return 1; } @@ -69,8 +73,8 @@ static int b_or (lua_State *L) { int i, n = lua_gettop(L); lua_Unsigned r = 0; for (i = 1; i <= n; i++) - r |= luaL_checkunsigned(L, i); - lua_pushunsigned(L, trim(r)); + r |= checkunsigned(L, i); + pushunsigned(L, trim(r)); return 1; } @@ -79,15 +83,15 @@ static int b_xor (lua_State *L) { int i, n = lua_gettop(L); lua_Unsigned r = 0; for (i = 1; i <= n; i++) - r ^= luaL_checkunsigned(L, i); - lua_pushunsigned(L, trim(r)); + r ^= checkunsigned(L, i); + pushunsigned(L, trim(r)); return 1; } static int b_not (lua_State *L) { - lua_Unsigned r = ~luaL_checkunsigned(L, 1); - lua_pushunsigned(L, trim(r)); + lua_Unsigned r = ~checkunsigned(L, 1); + pushunsigned(L, trim(r)); return 1; } @@ -104,23 +108,23 @@ static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) { else r <<= i; r = trim(r); } - lua_pushunsigned(L, r); + pushunsigned(L, r); return 1; } static int b_lshift (lua_State *L) { - return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkinteger(L, 2)); + return b_shift(L, checkunsigned(L, 1), luaL_checkinteger(L, 2)); } static int b_rshift (lua_State *L) { - return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkinteger(L, 2)); + return b_shift(L, checkunsigned(L, 1), -luaL_checkinteger(L, 2)); } static int b_arshift (lua_State *L) { - lua_Unsigned r = luaL_checkunsigned(L, 1); + lua_Unsigned r = checkunsigned(L, 1); lua_Integer i = luaL_checkinteger(L, 2); if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1)))) return b_shift(L, r, -i); @@ -128,19 +132,19 @@ static int b_arshift (lua_State *L) { if (i >= LUA_NBITS) r = ALLONES; else r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i)); /* add signal bit */ - lua_pushunsigned(L, r); + pushunsigned(L, r); return 1; } } static int b_rot (lua_State *L, lua_Integer d) { - lua_Unsigned r = luaL_checkunsigned(L, 1); + lua_Unsigned r = checkunsigned(L, 1); int i = d & (LUA_NBITS - 1); /* i = d % NBITS */ r = trim(r); if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */ r = (r << i) | (r >> (LUA_NBITS - i)); - lua_pushunsigned(L, trim(r)); + pushunsigned(L, trim(r)); return 1; } @@ -175,23 +179,22 @@ static int fieldargs (lua_State *L, int farg, int *width) { static int b_extract (lua_State *L) { int w; - lua_Unsigned r = trim(luaL_checkunsigned(L, 1)); + lua_Unsigned r = trim(checkunsigned(L, 1)); int f = fieldargs(L, 2, &w); r = (r >> f) & mask(w); - lua_pushunsigned(L, r); + pushunsigned(L, r); return 1; } static int b_replace (lua_State *L) { int w; - lua_Unsigned r = trim(luaL_checkunsigned(L, 1)); - lua_Unsigned v = luaL_checkunsigned(L, 2); + lua_Unsigned r = trim(checkunsigned(L, 1)); + lua_Unsigned v = trim(checkunsigned(L, 2)); int f = fieldargs(L, 3, &w); - int m = mask(w); - v &= m; /* erase bits outside given width */ - r = (r & ~(m << f)) | (v << f); - lua_pushunsigned(L, r); + lua_Unsigned m = mask(w); + r = (r & ~(m << f)) | ((v & m) << f); + pushunsigned(L, r); return 1; } diff --git a/source/extern/lua/lcode.c b/source/extern/lua/lcode.c index d6f0fcd..dc7271d 100644 --- a/source/extern/lua/lcode.c +++ b/source/extern/lua/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 2.101 2015/04/29 18:24:11 roberto Exp $ +** $Id: lcode.c,v 2.112.1.1 2017/04/19 17:20:42 roberto Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -36,8 +36,12 @@ #define hasjumps(e) ((e)->t != (e)->f) -static int tonumeral(expdesc *e, TValue *v) { - if (e->t != NO_JUMP || e->f != NO_JUMP) +/* +** If expression is a numeric constant, fills 'v' with its value +** and returns 1. Otherwise, returns 0. +*/ +static int tonumeral(const expdesc *e, TValue *v) { + if (hasjumps(e)) return 0; /* not a numeral */ switch (e->k) { case VKINT: @@ -51,13 +55,19 @@ static int tonumeral(expdesc *e, TValue *v) { } +/* +** Create a OP_LOADNIL instruction, but try to optimize: if the previous +** instruction is also OP_LOADNIL and ranges are compatible, adjust +** range of previous instruction instead of emitting a new one. (For +** instance, 'local a; local b' will generate a single opcode.) +*/ void luaK_nil (FuncState *fs, int from, int n) { Instruction *previous; int l = from + n - 1; /* last register to set nil */ if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ previous = &fs->f->code[fs->pc-1]; - if (GET_OPCODE(*previous) == OP_LOADNIL) { - int pfrom = GETARG_A(*previous); + if (GET_OPCODE(*previous) == OP_LOADNIL) { /* previous is LOADNIL? */ + int pfrom = GETARG_A(*previous); /* get previous range */ int pl = pfrom + GETARG_B(*previous); if ((pfrom <= from && from <= pl + 1) || (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */ @@ -73,37 +83,84 @@ void luaK_nil (FuncState *fs, int from, int n) { } +/* +** Gets the destination address of a jump instruction. Used to traverse +** a list of jumps. +*/ +static int getjump (FuncState *fs, int pc) { + int offset = GETARG_sBx(fs->f->code[pc]); + if (offset == NO_JUMP) /* point to itself represents end of list */ + return NO_JUMP; /* end of list */ + else + return (pc+1)+offset; /* turn offset into absolute position */ +} + + +/* +** Fix jump instruction at position 'pc' to jump to 'dest'. +** (Jump addresses are relative in Lua) +*/ +static void fixjump (FuncState *fs, int pc, int dest) { + Instruction *jmp = &fs->f->code[pc]; + int offset = dest - (pc + 1); + lua_assert(dest != NO_JUMP); + if (abs(offset) > MAXARG_sBx) + luaX_syntaxerror(fs->ls, "control structure too long"); + SETARG_sBx(*jmp, offset); +} + + +/* +** Concatenate jump-list 'l2' into jump-list 'l1' +*/ +void luaK_concat (FuncState *fs, int *l1, int l2) { + if (l2 == NO_JUMP) return; /* nothing to concatenate? */ + else if (*l1 == NO_JUMP) /* no original list? */ + *l1 = l2; /* 'l1' points to 'l2' */ + else { + int list = *l1; + int next; + while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ + list = next; + fixjump(fs, list, l2); /* last element links to 'l2' */ + } +} + + +/* +** Create a jump instruction and return its position, so its destination +** can be fixed later (with 'fixjump'). If there are jumps to +** this position (kept in 'jpc'), link them all together so that +** 'patchlistaux' will fix all them directly to the final destination. +*/ int luaK_jump (FuncState *fs) { int jpc = fs->jpc; /* save list of jumps to here */ int j; - fs->jpc = NO_JUMP; + fs->jpc = NO_JUMP; /* no more jumps to here */ j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); luaK_concat(fs, &j, jpc); /* keep them on hold */ return j; } +/* +** Code a 'return' instruction +*/ void luaK_ret (FuncState *fs, int first, int nret) { luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); } +/* +** Code a "conditional jump", that is, a test or comparison opcode +** followed by a jump. Return jump position. +*/ static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { luaK_codeABC(fs, op, A, B, C); return luaK_jump(fs); } -static void fixjump (FuncState *fs, int pc, int dest) { - Instruction *jmp = &fs->f->code[pc]; - int offset = dest-(pc+1); - lua_assert(dest != NO_JUMP); - if (abs(offset) > MAXARG_sBx) - luaX_syntaxerror(fs->ls, "control structure too long"); - SETARG_sBx(*jmp, offset); -} - - /* ** returns current 'pc' and marks it as a jump target (to avoid wrong ** optimizations with consecutive instructions not in the same basic block). @@ -114,15 +171,11 @@ int luaK_getlabel (FuncState *fs) { } -static int getjump (FuncState *fs, int pc) { - int offset = GETARG_sBx(fs->f->code[pc]); - if (offset == NO_JUMP) /* point to itself represents end of list */ - return NO_JUMP; /* end of list */ - else - return (pc+1)+offset; /* turn offset into absolute position */ -} - - +/* +** Returns the position of the instruction "controlling" a given +** jump (that is, its condition), or the jump itself if it is +** unconditional. +*/ static Instruction *getjumpcontrol (FuncState *fs, int pc) { Instruction *pi = &fs->f->code[pc]; if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) @@ -133,37 +186,41 @@ static Instruction *getjumpcontrol (FuncState *fs, int pc) { /* -** check whether list has any jump that do not produce a value -** (or produce an inverted value) +** Patch destination register for a TESTSET instruction. +** If instruction in position 'node' is not a TESTSET, return 0 ("fails"). +** Otherwise, if 'reg' is not 'NO_REG', set it as the destination +** register. Otherwise, change instruction to a simple 'TEST' (produces +** no register value) */ -static int need_value (FuncState *fs, int list) { - for (; list != NO_JUMP; list = getjump(fs, list)) { - Instruction i = *getjumpcontrol(fs, list); - if (GET_OPCODE(i) != OP_TESTSET) return 1; - } - return 0; /* not found */ -} - - static int patchtestreg (FuncState *fs, int node, int reg) { Instruction *i = getjumpcontrol(fs, node); if (GET_OPCODE(*i) != OP_TESTSET) return 0; /* cannot patch other instructions */ if (reg != NO_REG && reg != GETARG_B(*i)) SETARG_A(*i, reg); - else /* no register to put value or register already has the value */ + else { + /* no register to put value or register already has the value; + change instruction to simple test */ *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); - + } return 1; } +/* +** Traverse a list of tests ensuring no one produces a value +*/ static void removevalues (FuncState *fs, int list) { for (; list != NO_JUMP; list = getjump(fs, list)) patchtestreg(fs, list, NO_REG); } +/* +** Traverse a list of tests, patching their destination address and +** registers: tests producing values jump to 'vtarget' (and put their +** values in 'reg'), other tests jump to 'dtarget'. +*/ static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, int dtarget) { while (list != NO_JUMP) { @@ -177,15 +234,35 @@ static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, } +/* +** Ensure all pending jumps to current position are fixed (jumping +** to current position with no values) and reset list of pending +** jumps +*/ static void dischargejpc (FuncState *fs) { patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); fs->jpc = NO_JUMP; } +/* +** Add elements in 'list' to list of pending jumps to "here" +** (current position) +*/ +void luaK_patchtohere (FuncState *fs, int list) { + luaK_getlabel(fs); /* mark "here" as a jump target */ + luaK_concat(fs, &fs->jpc, list); +} + + +/* +** Path all jumps in 'list' to jump to 'target'. +** (The assert means that we cannot fix a jump to a forward address +** because we only know addresses once code is generated.) +*/ void luaK_patchlist (FuncState *fs, int list, int target) { - if (target == fs->pc) - luaK_patchtohere(fs, list); + if (target == fs->pc) /* 'target' is current position? */ + luaK_patchtohere(fs, list); /* add list to pending jumps */ else { lua_assert(target < fs->pc); patchlistaux(fs, list, target, NO_REG, target); @@ -193,39 +270,26 @@ void luaK_patchlist (FuncState *fs, int list, int target) { } +/* +** Path all jumps in 'list' to close upvalues up to given 'level' +** (The assertion checks that jumps either were closing nothing +** or were closing higher levels, from inner blocks.) +*/ void luaK_patchclose (FuncState *fs, int list, int level) { level++; /* argument is +1 to reserve 0 as non-op */ - while (list != NO_JUMP) { - int next = getjump(fs, list); + for (; list != NO_JUMP; list = getjump(fs, list)) { lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP && (GETARG_A(fs->f->code[list]) == 0 || GETARG_A(fs->f->code[list]) >= level)); SETARG_A(fs->f->code[list], level); - list = next; - } -} - - -void luaK_patchtohere (FuncState *fs, int list) { - luaK_getlabel(fs); - luaK_concat(fs, &fs->jpc, list); -} - - -void luaK_concat (FuncState *fs, int *l1, int l2) { - if (l2 == NO_JUMP) return; - else if (*l1 == NO_JUMP) - *l1 = l2; - else { - int list = *l1; - int next; - while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ - list = next; - fixjump(fs, list, l2); } } +/* +** Emit instruction 'i', checking for array sizes and saving also its +** line information. Return 'i' position. +*/ static int luaK_code (FuncState *fs, Instruction i) { Proto *f = fs->f; dischargejpc(fs); /* 'pc' will change */ @@ -241,6 +305,10 @@ static int luaK_code (FuncState *fs, Instruction i) { } +/* +** Format and emit an 'iABC' instruction. (Assertions check consistency +** of parameters versus opcode.) +*/ int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { lua_assert(getOpMode(o) == iABC); lua_assert(getBMode(o) != OpArgN || b == 0); @@ -250,6 +318,9 @@ int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { } +/* +** Format and emit an 'iABx' instruction. +*/ int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); lua_assert(getCMode(o) == OpArgN); @@ -258,12 +329,20 @@ int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { } +/* +** Emit an "extra argument" instruction (format 'iAx') +*/ static int codeextraarg (FuncState *fs, int a) { lua_assert(a <= MAXARG_Ax); return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); } +/* +** Emit a "load constant" instruction, using either 'OP_LOADK' +** (if constant index 'k' fits in 18 bits) or an 'OP_LOADKX' +** instruction with "extra argument". +*/ int luaK_codek (FuncState *fs, int reg, int k) { if (k <= MAXARG_Bx) return luaK_codeABx(fs, OP_LOADK, reg, k); @@ -275,6 +354,10 @@ int luaK_codek (FuncState *fs, int reg, int k) { } +/* +** Check register-stack level, keeping track of its maximum size +** in field 'maxstacksize' +*/ void luaK_checkstack (FuncState *fs, int n) { int newstack = fs->freereg + n; if (newstack > fs->f->maxstacksize) { @@ -286,12 +369,20 @@ void luaK_checkstack (FuncState *fs, int n) { } +/* +** Reserve 'n' registers in register stack +*/ void luaK_reserveregs (FuncState *fs, int n) { luaK_checkstack(fs, n); fs->freereg += n; } +/* +** Free register 'reg', if it is neither a constant index nor +** a local variable. +) +*/ static void freereg (FuncState *fs, int reg) { if (!ISK(reg) && reg >= fs->nactvar) { fs->freereg--; @@ -300,6 +391,9 @@ static void freereg (FuncState *fs, int reg) { } +/* +** Free register used by expression 'e' (if any) +*/ static void freeexp (FuncState *fs, expdesc *e) { if (e->k == VNONRELOC) freereg(fs, e->u.info); @@ -307,8 +401,29 @@ static void freeexp (FuncState *fs, expdesc *e) { /* +** Free registers used by expressions 'e1' and 'e2' (if any) in proper +** order. +*/ +static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) { + int r1 = (e1->k == VNONRELOC) ? e1->u.info : -1; + int r2 = (e2->k == VNONRELOC) ? e2->u.info : -1; + if (r1 > r2) { + freereg(fs, r1); + freereg(fs, r2); + } + else { + freereg(fs, r2); + freereg(fs, r1); + } +} + + +/* +** Add constant 'v' to prototype's list of constants (field 'k'). ** Use scanner's table to cache position of constants in constant list -** and try to reuse constants +** and try to reuse constants. Because some values should not be used +** as keys (nil cannot be a key, integer keys can collapse with float +** keys), the caller must provide a useful 'key' for indexing the cache. */ static int addk (FuncState *fs, TValue *key, TValue *v) { lua_State *L = fs->ls->L; @@ -337,17 +452,21 @@ static int addk (FuncState *fs, TValue *key, TValue *v) { } +/* +** Add a string to list of constants and return its index. +*/ int luaK_stringK (FuncState *fs, TString *s) { TValue o; setsvalue(fs->ls->L, &o, s); - return addk(fs, &o, &o); + return addk(fs, &o, &o); /* use string itself as key */ } /* -** Integers use userdata as keys to avoid collision with floats with same -** value; conversion to 'void*' used only for hashing, no "precision" -** problems +** Add an integer to list of constants and return its index. +** Integers use userdata as keys to avoid collision with floats with +** same value; conversion to 'void*' is used only for hashing, so there +** are no "precision" problems. */ int luaK_intK (FuncState *fs, lua_Integer n) { TValue k, o; @@ -356,21 +475,29 @@ int luaK_intK (FuncState *fs, lua_Integer n) { return addk(fs, &k, &o); } - +/* +** Add a float to list of constants and return its index. +*/ static int luaK_numberK (FuncState *fs, lua_Number r) { TValue o; setfltvalue(&o, r); - return addk(fs, &o, &o); + return addk(fs, &o, &o); /* use number itself as key */ } +/* +** Add a boolean to list of constants and return its index. +*/ static int boolK (FuncState *fs, int b) { TValue o; setbvalue(&o, b); - return addk(fs, &o, &o); + return addk(fs, &o, &o); /* use boolean itself as key */ } +/* +** Add nil to list of constants and return its index. +*/ static int nilK (FuncState *fs) { TValue k, v; setnilvalue(&v); @@ -380,54 +507,79 @@ static int nilK (FuncState *fs) { } +/* +** Fix an expression to return the number of results 'nresults'. +** Either 'e' is a multi-ret expression (function call or vararg) +** or 'nresults' is LUA_MULTRET (as any expression can satisfy that). +*/ void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { if (e->k == VCALL) { /* expression is an open function call? */ - SETARG_C(getcode(fs, e), nresults+1); + SETARG_C(getinstruction(fs, e), nresults + 1); } else if (e->k == VVARARG) { - SETARG_B(getcode(fs, e), nresults+1); - SETARG_A(getcode(fs, e), fs->freereg); + Instruction *pc = &getinstruction(fs, e); + SETARG_B(*pc, nresults + 1); + SETARG_A(*pc, fs->freereg); luaK_reserveregs(fs, 1); } + else lua_assert(nresults == LUA_MULTRET); } +/* +** Fix an expression to return one result. +** If expression is not a multi-ret expression (function call or +** vararg), it already returns one result, so nothing needs to be done. +** Function calls become VNONRELOC expressions (as its result comes +** fixed in the base register of the call), while vararg expressions +** become VRELOCABLE (as OP_VARARG puts its results where it wants). +** (Calls are created returning one result, so that does not need +** to be fixed.) +*/ void luaK_setoneret (FuncState *fs, expdesc *e) { if (e->k == VCALL) { /* expression is an open function call? */ - e->k = VNONRELOC; - e->u.info = GETARG_A(getcode(fs, e)); + /* already returns 1 value */ + lua_assert(GETARG_C(getinstruction(fs, e)) == 2); + e->k = VNONRELOC; /* result has fixed position */ + e->u.info = GETARG_A(getinstruction(fs, e)); } else if (e->k == VVARARG) { - SETARG_B(getcode(fs, e), 2); + SETARG_B(getinstruction(fs, e), 2); e->k = VRELOCABLE; /* can relocate its simple result */ } } +/* +** Ensure that expression 'e' is not a variable. +*/ void luaK_dischargevars (FuncState *fs, expdesc *e) { switch (e->k) { - case VLOCAL: { - e->k = VNONRELOC; + case VLOCAL: { /* already in a register */ + e->k = VNONRELOC; /* becomes a non-relocatable value */ break; } - case VUPVAL: { + case VUPVAL: { /* move value to some (pending) register */ e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); e->k = VRELOCABLE; break; } case VINDEXED: { - OpCode op = OP_GETTABUP; /* assume 't' is in an upvalue */ + OpCode op; freereg(fs, e->u.ind.idx); - if (e->u.ind.vt == VLOCAL) { /* 't' is in a register? */ + if (e->u.ind.vt == VLOCAL) { /* is 't' in a register? */ freereg(fs, e->u.ind.t); op = OP_GETTABLE; } + else { + lua_assert(e->u.ind.vt == VUPVAL); + op = OP_GETTABUP; /* 't' is in an upvalue */ + } e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx); e->k = VRELOCABLE; break; } - case VVARARG: - case VCALL: { + case VVARARG: case VCALL: { luaK_setoneret(fs, e); break; } @@ -436,12 +588,10 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { } -static int code_label (FuncState *fs, int A, int b, int jump) { - luaK_getlabel(fs); /* those instructions may be jump targets */ - return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); -} - - +/* +** Ensures expression value is in register 'reg' (and therefore +** 'e' will become a non-relocatable expression). +*/ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { luaK_dischargevars(fs, e); switch (e->k) { @@ -466,8 +616,8 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { break; } case VRELOCABLE: { - Instruction *pc = &getcode(fs, e); - SETARG_A(*pc, reg); + Instruction *pc = &getinstruction(fs, e); + SETARG_A(*pc, reg); /* instruction will put result in 'reg' */ break; } case VNONRELOC: { @@ -476,7 +626,7 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { break; } default: { - lua_assert(e->k == VVOID || e->k == VJMP); + lua_assert(e->k == VJMP); return; /* nothing to do... */ } } @@ -485,17 +635,46 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { } +/* +** Ensures expression value is in any register. +*/ static void discharge2anyreg (FuncState *fs, expdesc *e) { - if (e->k != VNONRELOC) { - luaK_reserveregs(fs, 1); - discharge2reg(fs, e, fs->freereg-1); + if (e->k != VNONRELOC) { /* no fixed register yet? */ + luaK_reserveregs(fs, 1); /* get a register */ + discharge2reg(fs, e, fs->freereg-1); /* put value there */ } } +static int code_loadbool (FuncState *fs, int A, int b, int jump) { + luaK_getlabel(fs); /* those instructions may be jump targets */ + return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); +} + + +/* +** check whether list has any jump that do not produce a value +** or produce an inverted value +*/ +static int need_value (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) { + Instruction i = *getjumpcontrol(fs, list); + if (GET_OPCODE(i) != OP_TESTSET) return 1; + } + return 0; /* not found */ +} + + +/* +** Ensures final expression result (including results from its jump +** lists) is in register 'reg'. +** If expression has jumps, need to patch these jumps either to +** its final position or to "load" instructions (for those tests +** that do not produce values). +*/ static void exp2reg (FuncState *fs, expdesc *e, int reg) { discharge2reg(fs, e, reg); - if (e->k == VJMP) + if (e->k == VJMP) /* expression itself is a test? */ luaK_concat(fs, &e->t, e->u.info); /* put this jump in 't' list */ if (hasjumps(e)) { int final; /* position after whole expression */ @@ -503,8 +682,8 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) { int p_t = NO_JUMP; /* position of an eventual LOAD true */ if (need_value(fs, e->t) || need_value(fs, e->f)) { int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); - p_f = code_label(fs, reg, 0, 1); - p_t = code_label(fs, reg, 1, 0); + p_f = code_loadbool(fs, reg, 0, 1); + p_t = code_loadbool(fs, reg, 1, 0); luaK_patchtohere(fs, fj); } final = luaK_getlabel(fs); @@ -517,6 +696,10 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) { } +/* +** Ensures final expression result (including results from its jump +** lists) is in next available register. +*/ void luaK_exp2nextreg (FuncState *fs, expdesc *e) { luaK_dischargevars(fs, e); freeexp(fs, e); @@ -525,26 +708,39 @@ void luaK_exp2nextreg (FuncState *fs, expdesc *e) { } +/* +** Ensures final expression result (including results from its jump +** lists) is in some (any) register and return that register. +*/ int luaK_exp2anyreg (FuncState *fs, expdesc *e) { luaK_dischargevars(fs, e); - if (e->k == VNONRELOC) { - if (!hasjumps(e)) return e->u.info; /* exp is already in a register */ + if (e->k == VNONRELOC) { /* expression already has a register? */ + if (!hasjumps(e)) /* no jumps? */ + return e->u.info; /* result is already in a register */ if (e->u.info >= fs->nactvar) { /* reg. is not a local? */ - exp2reg(fs, e, e->u.info); /* put value on it */ + exp2reg(fs, e, e->u.info); /* put final result in it */ return e->u.info; } } - luaK_exp2nextreg(fs, e); /* default */ + luaK_exp2nextreg(fs, e); /* otherwise, use next available register */ return e->u.info; } +/* +** Ensures final expression result is either in a register or in an +** upvalue. +*/ void luaK_exp2anyregup (FuncState *fs, expdesc *e) { if (e->k != VUPVAL || hasjumps(e)) luaK_exp2anyreg(fs, e); } +/* +** Ensures final expression result is either in a register or it is +** a constant. +*/ void luaK_exp2val (FuncState *fs, expdesc *e) { if (hasjumps(e)) luaK_exp2anyreg(fs, e); @@ -553,35 +749,26 @@ void luaK_exp2val (FuncState *fs, expdesc *e) { } +/* +** Ensures final expression result is in a valid R/K index +** (that is, it is either in a register or in 'k' with an index +** in the range of R/K indices). +** Returns R/K index. +*/ int luaK_exp2RK (FuncState *fs, expdesc *e) { luaK_exp2val(fs, e); - switch (e->k) { - case VTRUE: - case VFALSE: - case VNIL: { - if (fs->nk <= MAXINDEXRK) { /* constant fits in RK operand? */ - e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE)); - e->k = VK; - return RKASK(e->u.info); - } - else break; - } - case VKINT: { - e->u.info = luaK_intK(fs, e->u.ival); - e->k = VK; - goto vk; - } - case VKFLT: { - e->u.info = luaK_numberK(fs, e->u.nval); - e->k = VK; - } - /* FALLTHROUGH */ - case VK: { + switch (e->k) { /* move constants to 'k' */ + case VTRUE: e->u.info = boolK(fs, 1); goto vk; + case VFALSE: e->u.info = boolK(fs, 0); goto vk; + case VNIL: e->u.info = nilK(fs); goto vk; + case VKINT: e->u.info = luaK_intK(fs, e->u.ival); goto vk; + case VKFLT: e->u.info = luaK_numberK(fs, e->u.nval); goto vk; + case VK: vk: + e->k = VK; if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */ return RKASK(e->u.info); else break; - } default: break; } /* not a constant in the right range: put it in a register */ @@ -589,11 +776,14 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) { } +/* +** Generate code to store result of expression 'ex' into variable 'var'. +*/ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { switch (var->k) { case VLOCAL: { freeexp(fs, ex); - exp2reg(fs, ex, var->u.info); + exp2reg(fs, ex, var->u.info); /* compute 'ex' into proper place */ return; } case VUPVAL: { @@ -607,29 +797,32 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e); break; } - default: { - lua_assert(0); /* invalid var kind to store */ - break; - } + default: lua_assert(0); /* invalid var kind to store */ } freeexp(fs, ex); } +/* +** Emit SELF instruction (convert expression 'e' into 'e:key(e,'). +*/ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { int ereg; luaK_exp2anyreg(fs, e); ereg = e->u.info; /* register where 'e' was placed */ freeexp(fs, e); e->u.info = fs->freereg; /* base register for op_self */ - e->k = VNONRELOC; + e->k = VNONRELOC; /* self expression has a fixed register */ luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key)); freeexp(fs, key); } -static void invertjump (FuncState *fs, expdesc *e) { +/* +** Negate condition 'e' (where 'e' is a comparison). +*/ +static void negatecondition (FuncState *fs, expdesc *e) { Instruction *pc = getjumpcontrol(fs, e->u.info); lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && GET_OPCODE(*pc) != OP_TEST); @@ -637,9 +830,15 @@ static void invertjump (FuncState *fs, expdesc *e) { } +/* +** Emit instruction to jump if 'e' is 'cond' (that is, if 'cond' +** is true, code will jump if 'e' is true.) Return jump position. +** Optimize when 'e' is 'not' something, inverting the condition +** and removing the 'not'. +*/ static int jumponcond (FuncState *fs, expdesc *e, int cond) { if (e->k == VRELOCABLE) { - Instruction ie = getcode(fs, e); + Instruction ie = getinstruction(fs, e); if (GET_OPCODE(ie) == OP_NOT) { fs->pc--; /* remove previous OP_NOT */ return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); @@ -652,13 +851,16 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) { } +/* +** Emit code to go through if 'e' is true, jump otherwise. +*/ void luaK_goiftrue (FuncState *fs, expdesc *e) { - int pc; /* pc of last jump */ + int pc; /* pc of new jump */ luaK_dischargevars(fs, e); switch (e->k) { - case VJMP: { - invertjump(fs, e); - pc = e->u.info; + case VJMP: { /* condition? */ + negatecondition(fs, e); /* jump when it is false */ + pc = e->u.info; /* save jump position */ break; } case VK: case VKFLT: case VKINT: case VTRUE: { @@ -666,22 +868,25 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) { break; } default: { - pc = jumponcond(fs, e, 0); + pc = jumponcond(fs, e, 0); /* jump when false */ break; } } - luaK_concat(fs, &e->f, pc); /* insert last jump in 'f' list */ - luaK_patchtohere(fs, e->t); + luaK_concat(fs, &e->f, pc); /* insert new jump in false list */ + luaK_patchtohere(fs, e->t); /* true list jumps to here (to go through) */ e->t = NO_JUMP; } +/* +** Emit code to go through if 'e' is false, jump otherwise. +*/ void luaK_goiffalse (FuncState *fs, expdesc *e) { - int pc; /* pc of last jump */ + int pc; /* pc of new jump */ luaK_dischargevars(fs, e); switch (e->k) { case VJMP: { - pc = e->u.info; + pc = e->u.info; /* already jump if true */ break; } case VNIL: case VFALSE: { @@ -689,29 +894,32 @@ void luaK_goiffalse (FuncState *fs, expdesc *e) { break; } default: { - pc = jumponcond(fs, e, 1); + pc = jumponcond(fs, e, 1); /* jump if true */ break; } } - luaK_concat(fs, &e->t, pc); /* insert last jump in 't' list */ - luaK_patchtohere(fs, e->f); + luaK_concat(fs, &e->t, pc); /* insert new jump in 't' list */ + luaK_patchtohere(fs, e->f); /* false list jumps to here (to go through) */ e->f = NO_JUMP; } +/* +** Code 'not e', doing constant folding. +*/ static void codenot (FuncState *fs, expdesc *e) { luaK_dischargevars(fs, e); switch (e->k) { case VNIL: case VFALSE: { - e->k = VTRUE; + e->k = VTRUE; /* true == not nil == not false */ break; } case VK: case VKFLT: case VKINT: case VTRUE: { - e->k = VFALSE; + e->k = VFALSE; /* false == not "x" == not 0.5 == not 1 == not true */ break; } case VJMP: { - invertjump(fs, e); + negatecondition(fs, e); break; } case VRELOCABLE: @@ -722,30 +930,32 @@ static void codenot (FuncState *fs, expdesc *e) { e->k = VRELOCABLE; break; } - default: { - lua_assert(0); /* cannot happen */ - break; - } + default: lua_assert(0); /* cannot happen */ } /* interchange true and false lists */ { int temp = e->f; e->f = e->t; e->t = temp; } - removevalues(fs, e->f); + removevalues(fs, e->f); /* values are useless when negated */ removevalues(fs, e->t); } +/* +** Create expression 't[k]'. 't' must have its final result already in a +** register or upvalue. +*/ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { - lua_assert(!hasjumps(t)); - t->u.ind.t = t->u.info; - t->u.ind.idx = luaK_exp2RK(fs, k); - t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL - : check_exp(vkisinreg(t->k), VLOCAL); + lua_assert(!hasjumps(t) && (vkisinreg(t->k) || t->k == VUPVAL)); + t->u.ind.t = t->u.info; /* register or upvalue index */ + t->u.ind.idx = luaK_exp2RK(fs, k); /* R/K index for key */ + t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL : VLOCAL; t->k = VINDEXED; } /* -** return false if folding can raise an error +** Return false if folding can raise an error. +** Bitwise operations need operands convertible to integers; division +** operations cannot have 0 as divisor. */ static int validop (int op, TValue *v1, TValue *v2) { switch (op) { @@ -762,9 +972,11 @@ static int validop (int op, TValue *v1, TValue *v2) { /* -** Try to "constant-fold" an operation; return 1 iff successful +** Try to "constant-fold" an operation; return 1 iff successful. +** (In this case, 'e1' has the final result.) */ -static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) { +static int constfolding (FuncState *fs, int op, expdesc *e1, + const expdesc *e2) { TValue v1, v2, res; if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2)) return 0; /* non-numeric operands or not safe to fold */ @@ -773,7 +985,7 @@ static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) { e1->k = VKINT; e1->u.ival = ivalue(&res); } - else { /* folds neither NaN nor 0.0 (to avoid collapsing with -0.0) */ + else { /* folds neither NaN nor 0.0 (to avoid problems with -0.0) */ lua_Number n = fltvalue(&res); if (luai_numisnan(n) || n == 0) return 0; @@ -785,81 +997,100 @@ static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) { /* -** Code for binary and unary expressions that "produce values" -** (arithmetic operations, bitwise operations, concat, length). First -** try to do constant folding (only for numeric [arithmetic and -** bitwise] operations, which is what 'lua_arith' accepts). -** Expression to produce final result will be encoded in 'e1'. +** Emit code for unary expressions that "produce values" +** (everything but 'not'). +** Expression to produce final result will be encoded in 'e'. */ -static void codeexpval (FuncState *fs, OpCode op, - expdesc *e1, expdesc *e2, int line) { - lua_assert(op >= OP_ADD); - if (op <= OP_BNOT && constfolding(fs, (op - OP_ADD) + LUA_OPADD, e1, e2)) - return; /* result has been folded */ - else { - int o1, o2; - /* move operands to registers (if needed) */ - if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) { /* unary op? */ - o2 = 0; /* no second expression */ - o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */ - } - else { /* regular case (binary operators) */ - o2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */ - o1 = luaK_exp2RK(fs, e1); - } - if (o1 > o2) { /* free registers in proper order */ - freeexp(fs, e1); - freeexp(fs, e2); - } - else { - freeexp(fs, e2); - freeexp(fs, e1); - } - e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); /* generate opcode */ - e1->k = VRELOCABLE; /* all those operations are relocable */ - luaK_fixline(fs, line); - } +static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) { + int r = luaK_exp2anyreg(fs, e); /* opcodes operate only on registers */ + freeexp(fs, e); + e->u.info = luaK_codeABC(fs, op, 0, r, 0); /* generate opcode */ + e->k = VRELOCABLE; /* all those operations are relocatable */ + luaK_fixline(fs, line); } -static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, - expdesc *e2) { - int o1 = luaK_exp2RK(fs, e1); - int o2 = luaK_exp2RK(fs, e2); - freeexp(fs, e2); - freeexp(fs, e1); - if (cond == 0 && op != OP_EQ) { - int temp; /* exchange args to replace by '<' or '<=' */ - temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ - cond = 1; +/* +** Emit code for binary expressions that "produce values" +** (everything but logical operators 'and'/'or' and comparison +** operators). +** Expression to produce final result will be encoded in 'e1'. +** Because 'luaK_exp2RK' can free registers, its calls must be +** in "stack order" (that is, first on 'e2', which may have more +** recent registers to be released). +*/ +static void codebinexpval (FuncState *fs, OpCode op, + expdesc *e1, expdesc *e2, int line) { + int rk2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */ + int rk1 = luaK_exp2RK(fs, e1); + freeexps(fs, e1, e2); + e1->u.info = luaK_codeABC(fs, op, 0, rk1, rk2); /* generate opcode */ + e1->k = VRELOCABLE; /* all those operations are relocatable */ + luaK_fixline(fs, line); +} + + +/* +** Emit code for comparisons. +** 'e1' was already put in R/K form by 'luaK_infix'. +*/ +static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { + int rk1 = (e1->k == VK) ? RKASK(e1->u.info) + : check_exp(e1->k == VNONRELOC, e1->u.info); + int rk2 = luaK_exp2RK(fs, e2); + freeexps(fs, e1, e2); + switch (opr) { + case OPR_NE: { /* '(a ~= b)' ==> 'not (a == b)' */ + e1->u.info = condjump(fs, OP_EQ, 0, rk1, rk2); + break; + } + case OPR_GT: case OPR_GE: { + /* '(a > b)' ==> '(b < a)'; '(a >= b)' ==> '(b <= a)' */ + OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ); + e1->u.info = condjump(fs, op, 1, rk2, rk1); /* invert operands */ + break; + } + default: { /* '==', '<', '<=' use their own opcodes */ + OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ); + e1->u.info = condjump(fs, op, 1, rk1, rk2); + break; + } } - e1->u.info = condjump(fs, op, cond, o1, o2); e1->k = VJMP; } +/* +** Apply prefix operation 'op' to expression 'e'. +*/ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { - expdesc e2; - e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0; + static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP}; switch (op) { - case OPR_MINUS: case OPR_BNOT: case OPR_LEN: { - codeexpval(fs, cast(OpCode, (op - OPR_MINUS) + OP_UNM), e, &e2, line); + case OPR_MINUS: case OPR_BNOT: /* use 'ef' as fake 2nd operand */ + if (constfolding(fs, op + LUA_OPUNM, e, &ef)) + break; + /* FALLTHROUGH */ + case OPR_LEN: + codeunexpval(fs, cast(OpCode, op + OP_UNM), e, line); break; - } case OPR_NOT: codenot(fs, e); break; default: lua_assert(0); } } +/* +** Process 1st operand 'v' of binary operation 'op' before reading +** 2nd operand. +*/ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { switch (op) { case OPR_AND: { - luaK_goiftrue(fs, v); + luaK_goiftrue(fs, v); /* go ahead only if 'v' is true */ break; } case OPR_OR: { - luaK_goiffalse(fs, v); + luaK_goiffalse(fs, v); /* go ahead only if 'v' is false */ break; } case OPR_CONCAT: { @@ -871,7 +1102,9 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { case OPR_MOD: case OPR_POW: case OPR_BAND: case OPR_BOR: case OPR_BXOR: case OPR_SHL: case OPR_SHR: { - if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v); + if (!tonumeral(v, NULL)) + luaK_exp2RK(fs, v); + /* else keep numeral, which may be folded with 2nd operand */ break; } default: { @@ -882,18 +1115,24 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { } +/* +** Finalize code for binary operation, after reading 2nd operand. +** For '(a .. b .. c)' (which is '(a .. (b .. c))', because +** concatenation is right associative), merge second CONCAT into first +** one. +*/ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2, int line) { switch (op) { case OPR_AND: { - lua_assert(e1->t == NO_JUMP); /* list must be closed */ + lua_assert(e1->t == NO_JUMP); /* list closed by 'luK_infix' */ luaK_dischargevars(fs, e2); luaK_concat(fs, &e2->f, e1->f); *e1 = *e2; break; } case OPR_OR: { - lua_assert(e1->f == NO_JUMP); /* list must be closed */ + lua_assert(e1->f == NO_JUMP); /* list closed by 'luK_infix' */ luaK_dischargevars(fs, e2); luaK_concat(fs, &e2->t, e1->t); *e1 = *e2; @@ -901,15 +1140,16 @@ void luaK_posfix (FuncState *fs, BinOpr op, } case OPR_CONCAT: { luaK_exp2val(fs, e2); - if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { - lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1); + if (e2->k == VRELOCABLE && + GET_OPCODE(getinstruction(fs, e2)) == OP_CONCAT) { + lua_assert(e1->u.info == GETARG_B(getinstruction(fs, e2))-1); freeexp(fs, e1); - SETARG_B(getcode(fs, e2), e1->u.info); + SETARG_B(getinstruction(fs, e2), e1->u.info); e1->k = VRELOCABLE; e1->u.info = e2->u.info; } else { luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ - codeexpval(fs, OP_CONCAT, e1, e2, line); + codebinexpval(fs, OP_CONCAT, e1, e2, line); } break; } @@ -917,15 +1157,13 @@ void luaK_posfix (FuncState *fs, BinOpr op, case OPR_IDIV: case OPR_MOD: case OPR_POW: case OPR_BAND: case OPR_BOR: case OPR_BXOR: case OPR_SHL: case OPR_SHR: { - codeexpval(fs, cast(OpCode, (op - OPR_ADD) + OP_ADD), e1, e2, line); - break; - } - case OPR_EQ: case OPR_LT: case OPR_LE: { - codecomp(fs, cast(OpCode, (op - OPR_EQ) + OP_EQ), 1, e1, e2); + if (!constfolding(fs, op + LUA_OPADD, e1, e2)) + codebinexpval(fs, cast(OpCode, op + OP_ADD), e1, e2, line); break; } + case OPR_EQ: case OPR_LT: case OPR_LE: case OPR_NE: case OPR_GT: case OPR_GE: { - codecomp(fs, cast(OpCode, (op - OPR_NE) + OP_EQ), 0, e1, e2); + codecomp(fs, op, e1, e2); break; } default: lua_assert(0); @@ -933,15 +1171,25 @@ void luaK_posfix (FuncState *fs, BinOpr op, } +/* +** Change line information associated with current position. +*/ void luaK_fixline (FuncState *fs, int line) { fs->f->lineinfo[fs->pc - 1] = line; } +/* +** Emit a SETLIST instruction. +** 'base' is register that keeps table; +** 'nelems' is #table plus those to be stored now; +** 'tostore' is number of values (in registers 'base + 1',...) to add to +** table (or LUA_MULTRET to add up to stack top). +*/ void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; int b = (tostore == LUA_MULTRET) ? 0 : tostore; - lua_assert(tostore != 0); + lua_assert(tostore != 0 && tostore <= LFIELDS_PER_FLUSH); if (c <= MAXARG_C) luaK_codeABC(fs, OP_SETLIST, base, b, c); else if (c <= MAXARG_Ax) { diff --git a/source/extern/lua/lcode.h b/source/extern/lua/lcode.h index 43ab86d..882dc9c 100644 --- a/source/extern/lua/lcode.h +++ b/source/extern/lua/lcode.h @@ -1,5 +1,5 @@ /* -** $Id: lcode.h,v 1.63 2013/12/30 20:47:58 roberto Exp $ +** $Id: lcode.h,v 1.64.1.1 2017/04/19 17:20:42 roberto Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -40,7 +40,8 @@ typedef enum BinOpr { typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; -#define getcode(fs,e) ((fs)->f->code[(e)->u.info]) +/* get (pointer to) instruction of given 'expdesc' */ +#define getinstruction(fs,e) ((fs)->f->code[(e)->u.info]) #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) diff --git a/source/extern/lua/lcorolib.c b/source/extern/lua/lcorolib.c index 0c0b7fa..0b17af9 100644 --- a/source/extern/lua/lcorolib.c +++ b/source/extern/lua/lcorolib.c @@ -1,5 +1,5 @@ /* -** $Id: lcorolib.c,v 1.9 2014/11/02 19:19:04 roberto Exp $ +** $Id: lcorolib.c,v 1.10.1.1 2017/04/19 17:20:42 roberto Exp $ ** Coroutine Library ** See Copyright Notice in lua.h */ @@ -75,7 +75,7 @@ static int luaB_auxwrap (lua_State *L) { lua_State *co = lua_tothread(L, lua_upvalueindex(1)); int r = auxresume(L, co, lua_gettop(L)); if (r < 0) { - if (lua_isstring(L, -1)) { /* error object is a string? */ + if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */ luaL_where(L, 1); /* add extra info */ lua_insert(L, -2); lua_concat(L, 2); diff --git a/source/extern/lua/lctype.c b/source/extern/lua/lctype.c index ae9367e..f8ad7a2 100644 --- a/source/extern/lua/lctype.c +++ b/source/extern/lua/lctype.c @@ -1,5 +1,5 @@ /* -** $Id: lctype.c,v 1.12 2014/11/02 19:19:04 roberto Exp $ +** $Id: lctype.c,v 1.12.1.1 2017/04/19 17:20:42 roberto Exp $ ** 'ctype' functions for Lua ** See Copyright Notice in lua.h */ diff --git a/source/extern/lua/lctype.h b/source/extern/lua/lctype.h index 99c7d12..b09b21a 100644 --- a/source/extern/lua/lctype.h +++ b/source/extern/lua/lctype.h @@ -1,5 +1,5 @@ /* -** $Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp $ +** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $ ** 'ctype' functions for Lua ** See Copyright Notice in lua.h */ diff --git a/source/extern/lua/ldblib.c b/source/extern/lua/ldblib.c index 9151458..9d29afb 100644 --- a/source/extern/lua/ldblib.c +++ b/source/extern/lua/ldblib.c @@ -1,5 +1,5 @@ /* -** $Id: ldblib.c,v 1.149 2015/02/19 17:06:21 roberto Exp $ +** $Id: ldblib.c,v 1.151.1.1 2017/04/19 17:20:42 roberto Exp $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ @@ -28,8 +28,8 @@ static const int HOOKKEY = 0; /* -** If L1 != L, L1 can be in any state, and therefore there is no -** garanties about its stack space; any push in L1 must be +** If L1 != L, L1 can be in any state, and therefore there are no +** guarantees about its stack space; any push in L1 must be ** checked. */ static void checkstack (lua_State *L, lua_State *L1, int n) { diff --git a/source/extern/lua/ldebug.c b/source/extern/lua/ldebug.c index f76582c..bb0e1d4 100644 --- a/source/extern/lua/ldebug.c +++ b/source/extern/lua/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.115 2015/05/22 17:45:56 roberto Exp $ +** $Id: ldebug.c,v 2.121.1.2 2017/07/10 17:21:50 roberto Exp $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -38,7 +38,8 @@ #define ci_func(ci) (clLvalue((ci)->func)) -static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); +static const char *funcnamefromcode (lua_State *L, CallInfo *ci, + const char **name); static int currentpc (CallInfo *ci) { @@ -69,7 +70,13 @@ static void swapextra (lua_State *L) { /* -** this function can be called asynchronous (e.g. during a signal) +** This function can be called asynchronously (e.g. during a signal). +** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by +** 'resethookcount') are for debug only, and it is no problem if they +** get arbitrary values (causes at most one wrong hook call). 'hookmask' +** is an atomic value. We assume that pointers are atomic too (e.g., gcc +** ensures that for all platforms where it runs). Moreover, 'hook' is +** always checked before being called (see 'luaD_hook'). */ LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { if (func == NULL || mask == 0) { /* turn off hooks? */ @@ -126,10 +133,11 @@ static const char *upvalname (Proto *p, int uv) { static const char *findvararg (CallInfo *ci, int n, StkId *pos) { int nparams = clLvalue(ci->func)->p->numparams; - if (n >= cast_int(ci->u.l.base - ci->func) - nparams) + int nvararg = cast_int(ci->u.l.base - ci->func) - nparams; + if (n <= -nvararg) return NULL; /* no such vararg */ else { - *pos = ci->func + nparams + n; + *pos = ci->func + nparams - n; return "(*vararg)"; /* generic name for any vararg */ } } @@ -141,7 +149,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n, StkId base; if (isLua(ci)) { if (n < 0) /* access to vararg values? */ - return findvararg(ci, -n, pos); + return findvararg(ci, n, pos); else { base = ci->u.l.base; name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); @@ -238,6 +246,20 @@ static void collectvalidlines (lua_State *L, Closure *f) { } +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { + if (ci == NULL) /* no 'ci'? */ + return NULL; /* no info */ + else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */ + *name = "__gc"; + return "metamethod"; /* report it as such */ + } + /* calling function is a known Lua function? */ + else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous)) + return funcnamefromcode(L, ci->previous, name); + else return NULL; /* no way to find a name */ +} + + static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, Closure *f, CallInfo *ci) { int status = 1; @@ -268,11 +290,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, break; } case 'n': { - /* calling function is a known Lua function? */ - if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous)) - ar->namewhat = getfuncname(L, ci->previous, &ar->name); - else - ar->namewhat = NULL; + ar->namewhat = getfuncname(L, ci, &ar->name); if (ar->namewhat == NULL) { ar->namewhat = ""; /* not found */ ar->name = NULL; @@ -465,8 +483,15 @@ static const char *getobjname (Proto *p, int lastpc, int reg, } -static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { - TMS tm = (TMS)0; /* to avoid warnings */ +/* +** Try to find a name for a function based on the code that called it. +** (Only works when function was called by a Lua function.) +** Returns what the name is (e.g., "for iterator", "method", +** "metamethod") and sets '*name' to point to the name. +*/ +static const char *funcnamefromcode (lua_State *L, CallInfo *ci, + const char **name) { + TMS tm = (TMS)0; /* (initial value avoids warnings) */ Proto *p = ci_func(ci)->p; /* calling function */ int pc = currentpc(ci); /* calling instruction index */ Instruction i = p->code[pc]; /* calling instruction */ @@ -476,13 +501,13 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { } switch (GET_OPCODE(i)) { case OP_CALL: - case OP_TAILCALL: /* get function name */ - return getobjname(p, pc, GETARG_A(i), name); + case OP_TAILCALL: + return getobjname(p, pc, GETARG_A(i), name); /* get function name */ case OP_TFORCALL: { /* for iterator */ *name = "for iterator"; return "for iterator"; } - /* all other instructions can call only through metamethods */ + /* other instructions can do calls through metamethods */ case OP_SELF: case OP_GETTABUP: case OP_GETTABLE: tm = TM_INDEX; break; @@ -503,7 +528,8 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { case OP_EQ: tm = TM_EQ; break; case OP_LT: tm = TM_LT; break; case OP_LE: tm = TM_LE; break; - default: lua_assert(0); /* other instructions cannot call a function */ + default: + return NULL; /* cannot find a reasonable name */ } *name = getstr(G(L)->tmname[tm]); return "metamethod"; @@ -558,7 +584,7 @@ static const char *varinfo (lua_State *L, const TValue *o) { l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { - const char *t = objtypename(o); + const char *t = luaT_objtypename(L, o); luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o)); } @@ -590,9 +616,9 @@ l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) { l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { - const char *t1 = objtypename(p1); - const char *t2 = objtypename(p2); - if (t1 == t2) + const char *t1 = luaT_objtypename(L, p1); + const char *t2 = luaT_objtypename(L, p2); + if (strcmp(t1, t2) == 0) luaG_runerror(L, "attempt to compare two %s values", t1); else luaG_runerror(L, "attempt to compare %s with %s", t1, t2); @@ -618,7 +644,7 @@ l_noret luaG_errormsg (lua_State *L) { setobjs2s(L, L->top, L->top - 1); /* move argument */ setobjs2s(L, L->top - 1, errfunc); /* push function */ L->top++; /* assume EXTRA_STACK */ - luaD_call(L, L->top - 2, 1, 0); /* call it */ + luaD_callnoyield(L, L->top - 2, 1); /* call it */ } luaD_throw(L, LUA_ERRRUN); } @@ -628,6 +654,7 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { CallInfo *ci = L->ci; const char *msg; va_list argp; + luaC_checkGC(L); /* error message uses memory */ va_start(argp, fmt); msg = luaO_pushvfstring(L, fmt, argp); /* format message */ va_end(argp); @@ -640,9 +667,11 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { void luaG_traceexec (lua_State *L) { CallInfo *ci = L->ci; lu_byte mask = L->hookmask; - int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0); + int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); if (counthook) resethookcount(L); /* reset count */ + else if (!(mask & LUA_MASKLINE)) + return; /* no line hook and count != 0; nothing to be done */ if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ return; /* do not call hook again (VM yielded, so it did not move) */ diff --git a/source/extern/lua/ldebug.h b/source/extern/lua/ldebug.h index 0e31546..8cea0ee 100644 --- a/source/extern/lua/ldebug.h +++ b/source/extern/lua/ldebug.h @@ -1,5 +1,5 @@ /* -** $Id: ldebug.h,v 2.14 2015/05/22 17:45:56 roberto Exp $ +** $Id: ldebug.h,v 2.14.1.1 2017/04/19 17:20:42 roberto Exp $ ** Auxiliary functions from Debug Interface module ** See Copyright Notice in lua.h */ diff --git a/source/extern/lua/ldo.c b/source/extern/lua/ldo.c index 5c93a25..316e45c 100644 --- a/source/extern/lua/ldo.c +++ b/source/extern/lua/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 2.138 2015/05/22 17:48:19 roberto Exp $ +** $Id: ldo.c,v 2.157.1.1 2017/04/19 17:20:42 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -150,6 +150,11 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { /* }====================================================== */ +/* +** {================================================================== +** Stack reallocation +** =================================================================== +*/ static void correctstack (lua_State *L, TValue *oldstack) { CallInfo *ci; UpVal *up; @@ -206,9 +211,9 @@ static int stackinuse (lua_State *L) { CallInfo *ci; StkId lim = L->top; for (ci = L->ci; ci != NULL; ci = ci->previous) { - lua_assert(ci->top <= L->stack_last); if (lim < ci->top) lim = ci->top; } + lua_assert(lim <= L->stack_last); return cast_int(lim - L->stack) + 1; /* part of stack in use */ } @@ -216,22 +221,38 @@ static int stackinuse (lua_State *L) { void luaD_shrinkstack (lua_State *L) { int inuse = stackinuse(L); int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; - if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK; - if (L->stacksize > LUAI_MAXSTACK) /* was handling stack overflow? */ + if (goodsize > LUAI_MAXSTACK) + goodsize = LUAI_MAXSTACK; /* respect stack limit */ + if (L->stacksize > LUAI_MAXSTACK) /* had been handling stack overflow? */ luaE_freeCI(L); /* free all CIs (list grew because of an error) */ else luaE_shrinkCI(L); /* shrink list */ - if (inuse > LUAI_MAXSTACK || /* still handling stack overflow? */ - goodsize >= L->stacksize) /* would grow instead of shrink? */ - condmovestack(L); /* don't change stack (change only for debugging) */ - else - luaD_reallocstack(L, goodsize); /* shrink it */ + /* if thread is currently not handling a stack overflow and its + good size is smaller than current size, shrink its stack */ + if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && + goodsize < L->stacksize) + luaD_reallocstack(L, goodsize); + else /* don't change stack */ + condmovestack(L,{},{}); /* (change only for debugging) */ } +void luaD_inctop (lua_State *L) { + luaD_checkstack(L, 1); + L->top++; +} + +/* }================================================================== */ + + +/* +** Call a hook for the given event. Make sure there is a hook to be +** called. (Both 'L->hook' and 'L->hookmask', which triggers this +** function, can be changed asynchronously by signals.) +*/ void luaD_hook (lua_State *L, int event, int line) { lua_Hook hook = L->hook; - if (hook && L->allowhook) { + if (hook && L->allowhook) { /* make sure there is a hook */ CallInfo *ci = L->ci; ptrdiff_t top = savestack(L, L->top); ptrdiff_t ci_top = savestack(L, ci->top); @@ -273,15 +294,15 @@ static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { int i; int nfixargs = p->numparams; StkId base, fixed; - lua_assert(actual >= nfixargs); /* move fixed parameters to final position */ - luaD_checkstack(L, p->maxstacksize); /* check again for new 'base' */ fixed = L->top - actual; /* first fixed argument */ base = L->top; /* final position of first argument */ - for (i=0; itop++, fixed + i); - setnilvalue(fixed + i); + setnilvalue(fixed + i); /* erase original copy (for GC) */ } + for (; i < nfixargs; i++) + setnilvalue(L->top++); /* complete missing arguments */ return base; } @@ -304,85 +325,57 @@ static void tryfuncTM (lua_State *L, StkId func) { } - -#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) - - /* -** returns true if function has been executed (C function) +** Given 'nres' results at 'firstResult', move 'wanted' of them to 'res'. +** Handle most typical cases (zero results for commands, one result for +** expressions, multiple results for tail calls/single parameters) +** separated. */ -int luaD_precall (lua_State *L, StkId func, int nresults) { - lua_CFunction f; - CallInfo *ci; - int n; /* number of arguments (Lua) or returns (C) */ - ptrdiff_t funcr = savestack(L, func); - switch (ttype(func)) { - case LUA_TLCF: /* light C function */ - f = fvalue(func); - goto Cfunc; - case LUA_TCCL: { /* C closure */ - f = clCvalue(func)->f; - Cfunc: - luaC_checkGC(L); /* stack grow uses memory */ - luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ - ci = next_ci(L); /* now 'enter' new function */ - ci->nresults = nresults; - ci->func = restorestack(L, funcr); - ci->top = L->top + LUA_MINSTACK; - lua_assert(ci->top <= L->stack_last); - ci->callstatus = 0; - if (L->hookmask & LUA_MASKCALL) - luaD_hook(L, LUA_HOOKCALL, -1); - lua_unlock(L); - n = (*f)(L); /* do the actual call */ - lua_lock(L); - api_checknelems(L, n); - luaD_poscall(L, L->top - n, n); - return 1; +static int moveresults (lua_State *L, const TValue *firstResult, StkId res, + int nres, int wanted) { + switch (wanted) { /* handle typical cases separately */ + case 0: break; /* nothing to move */ + case 1: { /* one result needed */ + if (nres == 0) /* no results? */ + firstResult = luaO_nilobject; /* adjust with nil */ + setobjs2s(L, res, firstResult); /* move it to proper place */ + break; } - case LUA_TLCL: { /* Lua function: prepare its call */ - StkId base; - Proto *p = clLvalue(func)->p; - n = cast_int(L->top - func) - 1; /* number of real arguments */ - luaC_checkGC(L); /* stack grow uses memory */ - luaD_checkstack(L, p->maxstacksize); - for (; n < p->numparams; n++) - setnilvalue(L->top++); /* complete missing arguments */ - if (!p->is_vararg) { - func = restorestack(L, funcr); - base = func + 1; - } - else { - base = adjust_varargs(L, p, n); - func = restorestack(L, funcr); /* previous call can change stack */ - } - ci = next_ci(L); /* now 'enter' new function */ - ci->nresults = nresults; - ci->func = func; - ci->u.l.base = base; - ci->top = base + p->maxstacksize; - lua_assert(ci->top <= L->stack_last); - ci->u.l.savedpc = p->code; /* starting point */ - ci->callstatus = CIST_LUA; - L->top = ci->top; - if (L->hookmask & LUA_MASKCALL) - callhook(L, ci); - return 0; + case LUA_MULTRET: { + int i; + for (i = 0; i < nres; i++) /* move all results to correct place */ + setobjs2s(L, res + i, firstResult + i); + L->top = res + nres; + return 0; /* wanted == LUA_MULTRET */ } - default: { /* not a function */ - luaD_checkstack(L, 1); /* ensure space for metamethod */ - func = restorestack(L, funcr); /* previous call may change stack */ - tryfuncTM(L, func); /* try to get '__call' metamethod */ - return luaD_precall(L, func, nresults); /* now it must be a function */ + default: { + int i; + if (wanted <= nres) { /* enough results? */ + for (i = 0; i < wanted; i++) /* move wanted results to correct place */ + setobjs2s(L, res + i, firstResult + i); + } + else { /* not enough results; use all of them plus nils */ + for (i = 0; i < nres; i++) /* move all results to correct place */ + setobjs2s(L, res + i, firstResult + i); + for (; i < wanted; i++) /* complete wanted number of results */ + setnilvalue(res + i); + } + break; } } + L->top = res + wanted; /* top points after the last result */ + return 1; } -int luaD_poscall (lua_State *L, StkId firstResult, int nres) { +/* +** Finishes a function call: calls hook if necessary, removes CallInfo, +** moves current number of results to proper place; returns 0 iff call +** wanted multiple (variable number of) results. +*/ +int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { StkId res; - int wanted, i; - CallInfo *ci = L->ci; + int wanted = ci->nresults; if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { if (L->hookmask & LUA_MASKRET) { ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ @@ -392,15 +385,104 @@ int luaD_poscall (lua_State *L, StkId firstResult, int nres) { L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ } res = ci->func; /* res == final position of 1st result */ - wanted = ci->nresults; L->ci = ci->previous; /* back to caller */ - /* move results to correct place */ - for (i = wanted; i != 0 && nres-- > 0; i--) - setobjs2s(L, res++, firstResult++); - while (i-- > 0) - setnilvalue(res++); - L->top = res; - return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ + /* move results to proper place */ + return moveresults(L, firstResult, res, nres, wanted); +} + + + +#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) + + +/* macro to check stack size, preserving 'p' */ +#define checkstackp(L,n,p) \ + luaD_checkstackaux(L, n, \ + ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \ + luaC_checkGC(L), /* stack grow uses memory */ \ + p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ + + +/* +** Prepares a function call: checks the stack, creates a new CallInfo +** entry, fills in the relevant information, calls hook if needed. +** If function is a C function, does the call, too. (Otherwise, leave +** the execution ('luaV_execute') to the caller, to allow stackless +** calls.) Returns true iff function has been executed (C function). +*/ +int luaD_precall (lua_State *L, StkId func, int nresults) { + lua_CFunction f; + CallInfo *ci; + switch (ttype(func)) { + case LUA_TCCL: /* C closure */ + f = clCvalue(func)->f; + goto Cfunc; + case LUA_TLCF: /* light C function */ + f = fvalue(func); + Cfunc: { + int n; /* number of returns */ + checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ + ci = next_ci(L); /* now 'enter' new function */ + ci->nresults = nresults; + ci->func = func; + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); + ci->callstatus = 0; + if (L->hookmask & LUA_MASKCALL) + luaD_hook(L, LUA_HOOKCALL, -1); + lua_unlock(L); + n = (*f)(L); /* do the actual call */ + lua_lock(L); + api_checknelems(L, n); + luaD_poscall(L, ci, L->top - n, n); + return 1; + } + case LUA_TLCL: { /* Lua function: prepare its call */ + StkId base; + Proto *p = clLvalue(func)->p; + int n = cast_int(L->top - func) - 1; /* number of real arguments */ + int fsize = p->maxstacksize; /* frame size */ + checkstackp(L, fsize, func); + if (p->is_vararg) + base = adjust_varargs(L, p, n); + else { /* non vararg function */ + for (; n < p->numparams; n++) + setnilvalue(L->top++); /* complete missing arguments */ + base = func + 1; + } + ci = next_ci(L); /* now 'enter' new function */ + ci->nresults = nresults; + ci->func = func; + ci->u.l.base = base; + L->top = ci->top = base + fsize; + lua_assert(ci->top <= L->stack_last); + ci->u.l.savedpc = p->code; /* starting point */ + ci->callstatus = CIST_LUA; + if (L->hookmask & LUA_MASKCALL) + callhook(L, ci); + return 0; + } + default: { /* not a function */ + checkstackp(L, 1, func); /* ensure space for metamethod */ + tryfuncTM(L, func); /* try to get '__call' metamethod */ + return luaD_precall(L, func, nresults); /* now it must be a function */ + } + } +} + + +/* +** Check appropriate error for stack overflow ("regular" overflow or +** overflow while handling stack overflow). If 'nCalls' is larger than +** LUAI_MAXCCALLS (which means it is handling a "regular" overflow) but +** smaller than 9/8 of LUAI_MAXCCALLS, does not report an error (to +** allow overflow handling to work) +*/ +static void stackerror (lua_State *L) { + if (L->nCcalls == LUAI_MAXCCALLS) + luaG_runerror(L, "C stack overflow"); + else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) + luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ } @@ -410,21 +492,25 @@ int luaD_poscall (lua_State *L, StkId firstResult, int nres) { ** When returns, all the results are on the stack, starting at the original ** function position. */ -void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) { - if (++L->nCcalls >= LUAI_MAXCCALLS) { - if (L->nCcalls == LUAI_MAXCCALLS) - luaG_runerror(L, "C stack overflow"); - else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) - luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ - } - if (!allowyield) L->nny++; +void luaD_call (lua_State *L, StkId func, int nResults) { + if (++L->nCcalls >= LUAI_MAXCCALLS) + stackerror(L); if (!luaD_precall(L, func, nResults)) /* is a Lua function? */ luaV_execute(L); /* call it */ - if (!allowyield) L->nny--; L->nCcalls--; } +/* +** Similar to 'luaD_call', but does not allow yields during the call +*/ +void luaD_callnoyield (lua_State *L, StkId func, int nResults) { + L->nny++; + luaD_call(L, func, nResults); + L->nny--; +} + + /* ** Completes the execution of an interrupted C function, calling its ** continuation function. @@ -437,19 +523,17 @@ static void finishCcall (lua_State *L, int status) { /* error status can only happen in a protected call */ lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD); if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ - ci->callstatus &= ~CIST_YPCALL; /* finish 'lua_pcall' */ - L->errfunc = ci->u.c.old_errfunc; + ci->callstatus &= ~CIST_YPCALL; /* continuation is also inside it */ + L->errfunc = ci->u.c.old_errfunc; /* with the same error function */ } /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already handled */ adjustresults(L, ci->nresults); - /* call continuation function */ lua_unlock(L); - n = (*ci->u.c.k)(L, status, ci->u.c.ctx); + n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */ lua_lock(L); api_checknelems(L, n); - /* finish 'luaD_precall' */ - luaD_poscall(L, L->top - n, n); + luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_precall' */ } @@ -512,15 +596,16 @@ static int recover (lua_State *L, int status) { /* -** signal an error in the call to 'resume', not in the execution of the -** coroutine itself. (Such errors should not be handled by any coroutine -** error handler and should not kill the coroutine.) +** Signal an error in the call to 'lua_resume', not in the execution +** of the coroutine itself. (Such errors should not be handled by any +** coroutine error handler and should not kill the coroutine.) */ -static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) { - L->top = firstArg; /* remove args from the stack */ +static int resume_error (lua_State *L, const char *msg, int narg) { + L->top -= narg; /* remove args from the stack */ setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */ api_incr_top(L); - luaD_throw(L, -1); /* jump back to 'lua_resume' */ + lua_unlock(L); + return LUA_ERRRUN; } @@ -532,22 +617,15 @@ static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) { ** coroutine. */ static void resume (lua_State *L, void *ud) { - int nCcalls = L->nCcalls; int n = *(cast(int*, ud)); /* number of arguments */ StkId firstArg = L->top - n; /* first argument */ CallInfo *ci = L->ci; - if (nCcalls >= LUAI_MAXCCALLS) - resume_error(L, "C stack overflow", firstArg); - if (L->status == LUA_OK) { /* may be starting a coroutine */ - if (ci != &L->base_ci) /* not in base level? */ - resume_error(L, "cannot resume non-suspended coroutine", firstArg); - /* coroutine is in base level; start running it */ + if (L->status == LUA_OK) { /* starting a coroutine? */ if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ luaV_execute(L); /* call it */ } - else if (L->status != LUA_YIELD) - resume_error(L, "cannot resume dead coroutine", firstArg); else { /* resuming from previous yield */ + lua_assert(L->status == LUA_YIELD); L->status = LUA_OK; /* mark that it is running (again) */ ci->func = restorestack(L, ci->extra); if (isLua(ci)) /* yielded inside a hook? */ @@ -560,20 +638,27 @@ static void resume (lua_State *L, void *ud) { api_checknelems(L, n); firstArg = L->top - n; /* yield results come from continuation */ } - luaD_poscall(L, firstArg, n); /* finish 'luaD_precall' */ + luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_precall' */ } unroll(L, NULL); /* run continuation */ } - lua_assert(nCcalls == L->nCcalls); } LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { int status; - int oldnny = L->nny; /* save "number of non-yieldable" calls */ + unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */ lua_lock(L); - luai_userstateresume(L, nargs); + if (L->status == LUA_OK) { /* may be starting a coroutine */ + if (L->ci != &L->base_ci) /* not in base level? */ + return resume_error(L, "cannot resume non-suspended coroutine", nargs); + } + else if (L->status != LUA_YIELD) + return resume_error(L, "cannot resume dead coroutine", nargs); L->nCcalls = (from) ? from->nCcalls + 1 : 1; + if (L->nCcalls >= LUAI_MAXCCALLS) + return resume_error(L, "C stack overflow", nargs); + luai_userstateresume(L, nargs); L->nny = 0; /* allow yields */ api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); status = luaD_rawrunprotected(L, resume, &nargs); @@ -684,7 +769,7 @@ static void f_parser (lua_State *L, void *ud) { int c = zgetc(p->z); /* read first character */ if (c == LUA_SIGNATURE[0]) { checkmode(L, p->mode, "binary"); - cl = luaU_undump(L, p->z, &p->buff, p->name); + cl = luaU_undump(L, p->z, p->name); } else { checkmode(L, p->mode, "text"); diff --git a/source/extern/lua/ldo.h b/source/extern/lua/ldo.h index edade65..3b2983a 100644 --- a/source/extern/lua/ldo.h +++ b/source/extern/lua/ldo.h @@ -1,5 +1,5 @@ /* -** $Id: ldo.h,v 2.22 2015/05/22 17:48:19 roberto Exp $ +** $Id: ldo.h,v 2.29.1.1 2017/04/19 17:20:42 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -13,11 +13,21 @@ #include "lzio.h" -#define luaD_checkstack(L,n) if (L->stack_last - L->top <= (n)) \ - luaD_growstack(L, n); else condmovestack(L); +/* +** Macro to check stack size and grow stack if needed. Parameters +** 'pre'/'pos' allow the macro to preserve a pointer into the +** stack across reallocations, doing the work only when needed. +** 'condmovestack' is used in heavy tests to force a stack reallocation +** at every check. +*/ +#define luaD_checkstackaux(L,n,pre,pos) \ + if (L->stack_last - L->top <= (n)) \ + { pre; luaD_growstack(L, n); pos; } else { condmovestack(L,pre,pos); } + +/* In general, 'pre'/'pos' are empty (nothing to save) */ +#define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0) -#define incr_top(L) {L->top++; luaD_checkstack(L,0);} #define savestack(L,p) ((char *)(p) - (char *)L->stack) #define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) @@ -30,14 +40,16 @@ LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, const char *mode); LUAI_FUNC void luaD_hook (lua_State *L, int event, int line); LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); -LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults, - int allowyield); +LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); +LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, ptrdiff_t oldtop, ptrdiff_t ef); -LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult, int nres); +LUAI_FUNC int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, + int nres); LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); LUAI_FUNC void luaD_growstack (lua_State *L, int n); LUAI_FUNC void luaD_shrinkstack (lua_State *L); +LUAI_FUNC void luaD_inctop (lua_State *L); LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); diff --git a/source/extern/lua/ldump.c b/source/extern/lua/ldump.c index 4c04812..f025aca 100644 --- a/source/extern/lua/ldump.c +++ b/source/extern/lua/ldump.c @@ -1,5 +1,5 @@ /* -** $Id: ldump.c,v 2.36 2015/03/30 15:43:51 roberto Exp $ +** $Id: ldump.c,v 2.37.1.1 2017/04/19 17:20:42 roberto Exp $ ** save precompiled Lua chunks ** See Copyright Notice in lua.h */ @@ -38,7 +38,7 @@ typedef struct { static void DumpBlock (const void *b, size_t size, DumpState *D) { - if (D->status == 0) { + if (D->status == 0 && size > 0) { lua_unlock(D->L); D->status = (*D->writer)(D->L, b, size, D->data); lua_lock(D->L); diff --git a/source/extern/lua/lfunc.c b/source/extern/lua/lfunc.c index 67967da..ccafbb8 100644 --- a/source/extern/lua/lfunc.c +++ b/source/extern/lua/lfunc.c @@ -1,5 +1,5 @@ /* -** $Id: lfunc.c,v 2.45 2014/11/02 19:19:04 roberto Exp $ +** $Id: lfunc.c,v 2.45.1.1 2017/04/19 17:39:34 roberto Exp $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ diff --git a/source/extern/lua/lfunc.h b/source/extern/lua/lfunc.h index 2eeb0d5..c916e98 100644 --- a/source/extern/lua/lfunc.h +++ b/source/extern/lua/lfunc.h @@ -1,5 +1,5 @@ /* -** $Id: lfunc.h,v 2.15 2015/01/13 15:49:11 roberto Exp $ +** $Id: lfunc.h,v 2.15.1.1 2017/04/19 17:39:34 roberto Exp $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ diff --git a/source/extern/lua/lgc.c b/source/extern/lua/lgc.c index 973c269..db4df82 100644 --- a/source/extern/lua/lgc.c +++ b/source/extern/lua/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.205 2015/03/25 13:42:19 roberto Exp $ +** $Id: lgc.c,v 2.215.1.2 2017/08/31 16:15:27 roberto Exp $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -114,8 +114,13 @@ static void reallymarkobject (global_State *g, GCObject *o); /* -** if key is not marked, mark its entry as dead (therefore removing it -** from the table) +** If key is not marked, mark its entry as dead. This allows key to be +** collected, but keeps its entry in the table. A dead node is needed +** when Lua looks up for a key (it may be part of a chain) and when +** traversing a weak table (key might be removed from the table during +** traversal). Other places never manipulate dead keys, because its +** associated nil value is enough to signal that the entry is logically +** empty. */ static void removeentry (Node *n) { lua_assert(ttisnil(gval(n))); @@ -462,7 +467,7 @@ static lu_mem traversetable (global_State *g, Table *h) { else /* not weak */ traversestrongtable(g, h); return sizeof(Table) + sizeof(TValue) * h->sizearray + - sizeof(Node) * cast(size_t, sizenode(h)); + sizeof(Node) * cast(size_t, allocsizenode(h)); } @@ -534,7 +539,7 @@ static lu_mem traversethread (global_State *g, lua_State *th) { StkId lim = th->stack + th->stacksize; /* real end of stack */ for (; o < lim; o++) /* clear not-marked stack slice */ setnilvalue(o); - /* 'remarkupvals' may have removed thread from 'twups' list */ + /* 'remarkupvals' may have removed thread from 'twups' list */ if (!isintwups(th) && th->openupval != NULL) { th->twups = g->twups; /* link it back to the list */ g->twups = th; @@ -542,7 +547,8 @@ static lu_mem traversethread (global_State *g, lua_State *th) { } else if (g->gckind != KGC_EMERGENCY) luaD_shrinkstack(th); /* do not change stack in emergency cycle */ - return (sizeof(lua_State) + sizeof(TValue) * th->stacksize); + return (sizeof(lua_State) + sizeof(TValue) * th->stacksize + + sizeof(CallInfo) * th->nci); } @@ -637,8 +643,9 @@ static void clearkeys (global_State *g, GCObject *l, GCObject *f) { for (n = gnode(h, 0); n < limit; n++) { if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) { setnilvalue(gval(n)); /* remove value ... */ - removeentry(n); /* and remove entry from table */ } + if (ttisnil(gval(n))) /* is entry empty? */ + removeentry(n); /* remove entry from table */ } } } @@ -748,14 +755,11 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { /* ** sweep a list until a live object (or end of list) */ -static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) { +static GCObject **sweeptolive (lua_State *L, GCObject **p) { GCObject **old = p; - int i = 0; do { - i++; p = sweeplist(L, p, 1); } while (p == old); - if (n) *n += i; return p; } @@ -769,12 +773,11 @@ static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) { */ /* -** If possible, free concatenation buffer and shrink string table +** If possible, shrink string table */ static void checkSizes (lua_State *L, global_State *g) { if (g->gckind != KGC_EMERGENCY) { l_mem olddebt = g->GCdebt; - luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */ if (g->strt.nuse < g->strt.size / 4) /* string table too big? */ luaS_resize(L, g->strt.size / 2); /* shrink it a little */ g->GCestimate += g->GCdebt - olddebt; /* update estimate */ @@ -797,7 +800,7 @@ static GCObject *udata2finalize (global_State *g) { static void dothecall (lua_State *L, void *ud) { UNUSED(ud); - luaD_call(L, L->top - 2, 0, 0); + luaD_callnoyield(L, L->top - 2, 0); } @@ -816,7 +819,9 @@ static void GCTM (lua_State *L, int propagateerrors) { setobj2s(L, L->top, tm); /* push finalizer... */ setobj2s(L, L->top + 1, &v); /* ... and its argument */ L->top += 2; /* and (next line) call the finalizer */ + L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); + L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ L->allowhook = oldah; /* restore hooks */ g->gcrunning = running; /* restore state */ if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ @@ -851,10 +856,10 @@ static int runafewfinalizers (lua_State *L) { /* ** call all pending finalizers */ -static void callallpendingfinalizers (lua_State *L, int propagateerrors) { +static void callallpendingfinalizers (lua_State *L) { global_State *g = G(L); while (g->tobefnz) - GCTM(L, propagateerrors); + GCTM(L, 0); } @@ -904,7 +909,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { if (issweepphase(g)) { makewhite(g, o); /* "sweep" object 'o' */ if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */ - g->sweepgc = sweeptolive(L, g->sweepgc, NULL); /* change 'sweepgc' */ + g->sweepgc = sweeptolive(L, g->sweepgc); /* change 'sweepgc' */ } /* search for pointer pointing to 'o' */ for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ } @@ -946,19 +951,16 @@ static void setpause (global_State *g) { /* ** Enter first sweep phase. -** The call to 'sweeptolive' makes pointer point to an object inside -** the list (instead of to the header), so that the real sweep do not -** need to skip objects created between "now" and the start of the real -** sweep. -** Returns how many objects it swept. +** The call to 'sweeplist' tries to make pointer point to an object +** inside the list (instead of to the header), so that the real sweep do +** not need to skip objects created between "now" and the start of the +** real sweep. */ -static int entersweep (lua_State *L) { +static void entersweep (lua_State *L) { global_State *g = G(L); - int n = 0; g->gcstate = GCSswpallgc; lua_assert(g->sweepgc == NULL); - g->sweepgc = sweeptolive(L, &g->allgc, &n); - return n; + g->sweepgc = sweeplist(L, &g->allgc, 1); } @@ -966,7 +968,7 @@ void luaC_freeallobjects (lua_State *L) { global_State *g = G(L); separatetobefnz(g, 1); /* separate all objects with finalizers */ lua_assert(g->finobj == NULL); - callallpendingfinalizers(L, 0); + callallpendingfinalizers(L); lua_assert(g->tobefnz == NULL); g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */ g->gckind = KGC_NORMAL; @@ -1059,12 +1061,11 @@ static lu_mem singlestep (lua_State *L) { } case GCSatomic: { lu_mem work; - int sw; propagateall(g); /* make sure gray list is empty */ work = atomic(L); /* work is what was traversed by 'atomic' */ - sw = entersweep(L); + entersweep(L); g->GCestimate = gettotalbytes(g); /* first estimate */; - return work + sw * GCSWEEPCOST; + return work; } case GCSswpallgc: { /* sweep "regular" objects */ return sweepstep(L, g, GCSswpfinobj, &g->finobj); @@ -1114,9 +1115,12 @@ void luaC_runtilstate (lua_State *L, int statesmask) { static l_mem getdebt (global_State *g) { l_mem debt = g->GCdebt; int stepmul = g->gcstepmul; - debt = (debt / STEPMULADJ) + 1; - debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM; - return debt; + if (debt <= 0) return 0; /* minimal debt */ + else { + debt = (debt / STEPMULADJ) + 1; + debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM; + return debt; + } } /* diff --git a/source/extern/lua/lgc.h b/source/extern/lua/lgc.h index 0eedf84..425cd7c 100644 --- a/source/extern/lua/lgc.h +++ b/source/extern/lua/lgc.h @@ -1,5 +1,5 @@ /* -** $Id: lgc.h,v 2.86 2014/10/25 11:50:46 roberto Exp $ +** $Id: lgc.h,v 2.91.1.1 2017/04/19 17:39:34 roberto Exp $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -101,26 +101,35 @@ #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) -#define luaC_condGC(L,c) \ - {if (G(L)->GCdebt > 0) {c;}; condchangemem(L);} -#define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);) +/* +** Does one step of collection when debt becomes positive. 'pre'/'pos' +** allows some adjustments to be done only when needed. macro +** 'condchangemem' is used only for heavy tests (forcing a full +** GC cycle on every opportunity) +*/ +#define luaC_condGC(L,pre,pos) \ + { if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \ + condchangemem(L,pre,pos); } + +/* more often than not, 'pre'/'pos' are empty */ +#define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0) -#define luaC_barrier(L,p,v) { \ - if (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) \ - luaC_barrier_(L,obj2gco(p),gcvalue(v)); } +#define luaC_barrier(L,p,v) ( \ + (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ + luaC_barrier_(L,obj2gco(p),gcvalue(v)) : cast_void(0)) -#define luaC_barrierback(L,p,v) { \ - if (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) \ - luaC_barrierback_(L,p); } +#define luaC_barrierback(L,p,v) ( \ + (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ + luaC_barrierback_(L,p) : cast_void(0)) -#define luaC_objbarrier(L,p,o) { \ - if (isblack(p) && iswhite(o)) \ - luaC_barrier_(L,obj2gco(p),obj2gco(o)); } +#define luaC_objbarrier(L,p,o) ( \ + (isblack(p) && iswhite(o)) ? \ + luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0)) -#define luaC_upvalbarrier(L,uv) \ - { if (iscollectable((uv)->v) && !upisopen(uv)) \ - luaC_upvalbarrier_(L,uv); } +#define luaC_upvalbarrier(L,uv) ( \ + (iscollectable((uv)->v) && !upisopen(uv)) ? \ + luaC_upvalbarrier_(L,uv) : cast_void(0)) LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); LUAI_FUNC void luaC_freeallobjects (lua_State *L); diff --git a/source/extern/lua/linit.c b/source/extern/lua/linit.c index 8ce94cc..480da52 100644 --- a/source/extern/lua/linit.c +++ b/source/extern/lua/linit.c @@ -1,5 +1,5 @@ /* -** $Id: linit.c,v 1.38 2015/01/05 13:48:33 roberto Exp $ +** $Id: linit.c,v 1.39.1.1 2017/04/19 17:20:42 roberto Exp $ ** Initialization of libraries for lua.c and other clients ** See Copyright Notice in lua.h */ @@ -18,10 +18,10 @@ ** open the library, which is already linked to the application. ** For that, do the following code: ** -** luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); +** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); ** lua_pushcfunction(L, luaopen_modname); ** lua_setfield(L, -2, modname); -** lua_pop(L, 1); // remove _PRELOAD table +** lua_pop(L, 1); // remove PRELOAD table */ #include "lprefix.h" diff --git a/source/extern/lua/liolib.c b/source/extern/lua/liolib.c index 193cac6..027d4bd 100644 --- a/source/extern/lua/liolib.c +++ b/source/extern/lua/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 2.144 2015/04/03 18:41:57 roberto Exp $ +** $Id: liolib.c,v 2.151.1.1 2017/04/19 17:29:57 roberto Exp $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -23,18 +23,25 @@ #include "lualib.h" -#if !defined(l_checkmode) + /* -** Check whether 'mode' matches '[rwa]%+?b?'. ** Change this macro to accept other modes for 'fopen' besides ** the standard ones. */ -#define l_checkmode(mode) \ - (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \ - (*mode != '+' || ++mode) && /* skip if char is '+' */ \ - (*mode != 'b' || ++mode) && /* skip if char is 'b' */ \ - (*mode == '\0')) +#if !defined(l_checkmode) + +/* accepted extensions to 'mode' in 'fopen' */ +#if !defined(L_MODEEXT) +#define L_MODEEXT "b" +#endif + +/* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */ +static int l_checkmode (const char *mode) { + return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && + (*mode != '+' || (++mode, 1)) && /* skip if char is '+' */ + (strspn(mode, L_MODEEXT) == strlen(mode))); /* check extensions */ +} #endif @@ -176,7 +183,7 @@ static FILE *tofile (lua_State *L) { /* ** When creating file handles, always creates a 'closed' file handle ** before opening the actual file; so, if there is a memory error, the -** file is not left opened. +** handle is in a consistent state. */ static LStream *newprefile (lua_State *L) { LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream)); @@ -199,11 +206,16 @@ static int aux_close (lua_State *L) { } +static int f_close (lua_State *L) { + tofile(L); /* make sure argument is an open stream */ + return aux_close(L); +} + + static int io_close (lua_State *L) { if (lua_isnone(L, 1)) /* no argument? */ lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */ - tofile(L); /* make sure argument is an open stream */ - return aux_close(L); + return f_close(L); } @@ -265,6 +277,8 @@ static int io_popen (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); LStream *p = newprefile(L); + luaL_argcheck(L, ((mode[0] == 'r' || mode[0] == 'w') && mode[1] == '\0'), + 2, "invalid mode"); p->f = l_popen(L, filename, mode); p->closef = &io_pclose; return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; @@ -318,8 +332,15 @@ static int io_output (lua_State *L) { static int io_readline (lua_State *L); +/* +** maximum number of arguments to 'f:lines'/'io.lines' (it + 3 must fit +** in the limit for upvalues of a closure) +*/ +#define MAXARGLINE 250 + static void aux_lines (lua_State *L, int toclose) { int n = lua_gettop(L) - 1; /* number of arguments to read */ + luaL_argcheck(L, n <= MAXARGLINE, MAXARGLINE + 2, "too many arguments"); lua_pushinteger(L, n); /* number of arguments to read */ lua_pushboolean(L, toclose); /* close/not close file when finished */ lua_rotate(L, 2, 2); /* move 'n' and 'toclose' to their positions */ @@ -362,14 +383,17 @@ static int io_lines (lua_State *L) { /* maximum length of a numeral */ -#define MAXRN 200 +#if !defined (L_MAXLENNUM) +#define L_MAXLENNUM 200 +#endif + /* auxiliary structure used by 'read_number' */ typedef struct { FILE *f; /* file being read */ int c; /* current character (look ahead) */ int n; /* number of elements in buffer 'buff' */ - char buff[MAXRN + 1]; /* +1 for ending '\0' */ + char buff[L_MAXLENNUM + 1]; /* +1 for ending '\0' */ } RN; @@ -377,7 +401,7 @@ typedef struct { ** Add current char to buffer (if not out of space) and read next one */ static int nextc (RN *rn) { - if (rn->n >= MAXRN) { /* buffer overflow? */ + if (rn->n >= L_MAXLENNUM) { /* buffer overflow? */ rn->buff[0] = '\0'; /* invalidate result */ return 0; /* fail */ } @@ -390,10 +414,10 @@ static int nextc (RN *rn) { /* -** Accept current char if it is in 'set' (of size 1 or 2) +** Accept current char if it is in 'set' (of size 2) */ static int test2 (RN *rn, const char *set) { - if (rn->c == set[0] || (rn->c == set[1] && rn->c != '\0')) + if (rn->c == set[0] || rn->c == set[1]) return nextc(rn); else return 0; } @@ -422,11 +446,11 @@ static int read_number (lua_State *L, FILE *f) { char decp[2]; rn.f = f; rn.n = 0; decp[0] = lua_getlocaledecpoint(); /* get decimal point from locale */ - decp[1] = '\0'; + decp[1] = '.'; /* always accept a dot */ l_lockfile(rn.f); do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */ test2(&rn, "-+"); /* optional signal */ - if (test2(&rn, "0")) { + if (test2(&rn, "00")) { if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */ else count = 1; /* count initial '0' as a valid digit */ } @@ -462,7 +486,7 @@ static int read_line (lua_State *L, FILE *f, int chop) { int c = '\0'; luaL_buffinit(L, &b); while (c != EOF && c != '\n') { /* repeat until end of line */ - char *buff = luaL_prepbuffer(&b); /* pre-allocate buffer */ + char *buff = luaL_prepbuffer(&b); /* preallocate buffer */ int i = 0; l_lockfile(f); /* no memory errors can happen inside the lock */ while (i < LUAL_BUFFERSIZE && (c = l_getc(f)) != EOF && c != '\n') @@ -483,7 +507,7 @@ static void read_all (lua_State *L, FILE *f) { luaL_Buffer b; luaL_buffinit(L, &b); do { /* read file in chunks of LUAL_BUFFERSIZE bytes */ - char *p = luaL_prepbuffsize(&b, LUAL_BUFFERSIZE); + char *p = luaL_prepbuffer(&b); nr = fread(p, sizeof(char), LUAL_BUFFERSIZE, f); luaL_addsize(&b, nr); } while (nr == LUAL_BUFFERSIZE); @@ -602,8 +626,10 @@ static int g_write (lua_State *L, FILE *f, int arg) { if (lua_type(L, arg) == LUA_TNUMBER) { /* optimization: could be done exactly as for strings */ int len = lua_isinteger(L, arg) - ? fprintf(f, LUA_INTEGER_FMT, lua_tointeger(L, arg)) - : fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)); + ? fprintf(f, LUA_INTEGER_FMT, + (LUAI_UACINT)lua_tointeger(L, arg)) + : fprintf(f, LUA_NUMBER_FMT, + (LUAI_UACNUMBER)lua_tonumber(L, arg)); status = status && (len > 0); } else { @@ -693,7 +719,7 @@ static const luaL_Reg iolib[] = { ** methods for file handles */ static const luaL_Reg flib[] = { - {"close", io_close}, + {"close", f_close}, {"flush", f_flush}, {"lines", f_lines}, {"read", f_read}, diff --git a/source/extern/lua/llex.c b/source/extern/lua/llex.c index c35bd55..b6d9a46 100644 --- a/source/extern/lua/llex.c +++ b/source/extern/lua/llex.c @@ -1,5 +1,5 @@ /* -** $Id: llex.c,v 2.93 2015/05/22 17:45:56 roberto Exp $ +** $Id: llex.c,v 2.96.1.1 2017/04/19 17:20:42 roberto Exp $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ @@ -162,7 +162,6 @@ static void inclinenumber (LexState *ls) { void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source, int firstchar) { ls->t.token = 0; - ls->decpoint = '.'; ls->L = L; ls->current = firstchar; ls->lookahead.token = TK_EOS; /* no look-ahead token */ @@ -207,37 +206,6 @@ static int check_next2 (LexState *ls, const char *set) { } -/* -** change all characters 'from' in buffer to 'to' -*/ -static void buffreplace (LexState *ls, char from, char to) { - if (from != to) { - size_t n = luaZ_bufflen(ls->buff); - char *p = luaZ_buffer(ls->buff); - while (n--) - if (p[n] == from) p[n] = to; - } -} - - -#define buff2num(b,o) (luaO_str2num(luaZ_buffer(b), o) != 0) - -/* -** in case of format error, try to change decimal point separator to -** the one defined in the current locale and check again -*/ -static void trydecpoint (LexState *ls, TValue *o) { - char old = ls->decpoint; - ls->decpoint = lua_getlocaledecpoint(); - buffreplace(ls, old, ls->decpoint); /* try new decimal separator */ - if (!buff2num(ls->buff, o)) { - /* format error with correct decimal point: no more options */ - buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ - lexerror(ls, "malformed number", TK_FLT); - } -} - - /* LUA_NUMBER */ /* ** this function is quite liberal in what it accepts, as 'luaO_str2num' @@ -261,9 +229,8 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) { else break; } save(ls, '\0'); - buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ - if (!buff2num(ls->buff, &obj)) /* format error? */ - trydecpoint(ls, &obj); /* try to update decimal point separator */ + if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0) /* format error? */ + lexerror(ls, "malformed number", TK_FLT); if (ttisinteger(&obj)) { seminfo->i = ivalue(&obj); return TK_INT; @@ -277,12 +244,12 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) { /* -** skip a sequence '[=*[' or ']=*]'; if sequence is wellformed, return -** its number of '='s; otherwise, return a negative number (-1 iff there -** are no '='s after initial bracket) +** reads a sequence '[=*[' or ']=*]', leaving the last bracket. +** If sequence is well formed, return its number of '='s + 2; otherwise, +** return 1 if there is no '='s or 0 otherwise (an unfinished '[==...'). */ -static int skip_sep (LexState *ls) { - int count = 0; +static size_t skip_sep (LexState *ls) { + size_t count = 0; int s = ls->current; lua_assert(s == '[' || s == ']'); save_and_next(ls); @@ -290,11 +257,14 @@ static int skip_sep (LexState *ls) { save_and_next(ls); count++; } - return (ls->current == s) ? count : (-count) - 1; + return (ls->current == s) ? count + 2 + : (count == 0) ? 1 + : 0; + } -static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { +static void read_long_string (LexState *ls, SemInfo *seminfo, size_t sep) { int line = ls->linenumber; /* initial line (for error message) */ save_and_next(ls); /* skip 2nd '[' */ if (currIsNewline(ls)) /* string starts with a newline? */ @@ -328,8 +298,8 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { } } endloop: if (seminfo) - seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), - luaZ_bufflen(ls->buff) - 2*(2 + sep)); + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + sep, + luaZ_bufflen(ls->buff) - 2 * sep); } @@ -477,9 +447,9 @@ static int llex (LexState *ls, SemInfo *seminfo) { /* else is a comment */ next(ls); if (ls->current == '[') { /* long comment? */ - int sep = skip_sep(ls); + size_t sep = skip_sep(ls); luaZ_resetbuffer(ls->buff); /* 'skip_sep' may dirty the buffer */ - if (sep >= 0) { + if (sep >= 2) { read_long_string(ls, NULL, sep); /* skip long comment */ luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */ break; @@ -491,12 +461,12 @@ static int llex (LexState *ls, SemInfo *seminfo) { break; } case '[': { /* long string or simply '[' */ - int sep = skip_sep(ls); - if (sep >= 0) { + size_t sep = skip_sep(ls); + if (sep >= 2) { read_long_string(ls, seminfo, sep); return TK_STRING; } - else if (sep != -1) /* '[=...' missing second bracket */ + else if (sep == 0) /* '[=...' missing second bracket */ lexerror(ls, "invalid long string delimiter", TK_STRING); return '['; } diff --git a/source/extern/lua/llex.h b/source/extern/lua/llex.h index afb40b5..2ed0af6 100644 --- a/source/extern/lua/llex.h +++ b/source/extern/lua/llex.h @@ -1,5 +1,5 @@ /* -** $Id: llex.h,v 1.78 2014/10/29 15:38:24 roberto Exp $ +** $Id: llex.h,v 1.79.1.1 2017/04/19 17:20:42 roberto Exp $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ @@ -69,7 +69,6 @@ typedef struct LexState { struct Dyndata *dyd; /* dynamic structures used by the parser */ TString *source; /* current source name */ TString *envn; /* environment variable name */ - char decpoint; /* locale decimal point */ } LexState; diff --git a/source/extern/lua/llimits.h b/source/extern/lua/llimits.h index 277c724..d1036f6 100644 --- a/source/extern/lua/llimits.h +++ b/source/extern/lua/llimits.h @@ -1,5 +1,5 @@ /* -** $Id: llimits.h,v 1.135 2015/06/09 14:21:00 roberto Exp $ +** $Id: llimits.h,v 1.141.1.1 2017/04/19 17:20:42 roberto Exp $ ** Limits, basic types, and some other 'installation-dependent' definitions ** See Copyright Notice in lua.h */ @@ -64,7 +64,13 @@ typedef unsigned char lu_byte; #if defined(LUAI_USER_ALIGNMENT_T) typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; #else -typedef union { double u; void *s; lua_Integer i; long l; } L_Umaxalign; +typedef union { + lua_Number n; + double u; + void *s; + lua_Integer i; + long l; +} L_Umaxalign; #endif @@ -78,7 +84,7 @@ typedef LUAI_UACINT l_uacInt; #if defined(lua_assert) #define check_exp(c,e) (lua_assert(c), (e)) /* to avoid problems with conditions too long */ -#define lua_longassert(c) { if (!(c)) lua_assert(0); } +#define lua_longassert(c) ((c) ? (void)0 : lua_assert(0)) #else #define lua_assert(c) ((void)0) #define check_exp(c,e) (e) @@ -184,10 +190,13 @@ typedef unsigned long Instruction; /* -** Size of cache for strings in the API (better be a prime) +** Size of cache for strings in the API. 'N' is the number of +** sets (better be a prime) and "M" is the size of each set (M == 1 +** makes a direct cache.) */ -#if !defined(STRCACHE_SIZE) -#define STRCACHE_SIZE 127 +#if !defined(STRCACHE_N) +#define STRCACHE_N 53 +#define STRCACHE_M 2 #endif @@ -198,7 +207,7 @@ typedef unsigned long Instruction; /* -** macros that are executed whenether program enters the Lua core +** macros that are executed whenever program enters the Lua core ** ('lua_lock') and leaves the core ('lua_unlock') */ #if !defined(lua_lock) @@ -297,17 +306,18 @@ typedef unsigned long Instruction; ** macro to control inclusion of some hard tests on stack reallocation */ #if !defined(HARDSTACKTESTS) -#define condmovestack(L) ((void)0) +#define condmovestack(L,pre,pos) ((void)0) #else /* realloc stack keeping its size */ -#define condmovestack(L) luaD_reallocstack((L), (L)->stacksize) +#define condmovestack(L,pre,pos) \ + { int sz_ = (L)->stacksize; pre; luaD_reallocstack((L), sz_); pos; } #endif #if !defined(HARDMEMTESTS) -#define condchangemem(L) condmovestack(L) +#define condchangemem(L,pre,pos) ((void)0) #else -#define condchangemem(L) \ - ((void)(!(G(L)->gcrunning) || (luaC_fullgc(L, 0), 1))) +#define condchangemem(L,pre,pos) \ + { if (G(L)->gcrunning) { pre; luaC_fullgc(L, 0); pos; } } #endif #endif diff --git a/source/extern/lua/lmathlib.c b/source/extern/lua/lmathlib.c index 4f2ec60..7ef7e59 100644 --- a/source/extern/lua/lmathlib.c +++ b/source/extern/lua/lmathlib.c @@ -1,5 +1,5 @@ /* -** $Id: lmathlib.c,v 1.115 2015/03/12 14:04:04 roberto Exp $ +** $Id: lmathlib.c,v 1.119.1.1 2017/04/19 17:20:42 roberto Exp $ ** Standard mathematical library ** See Copyright Notice in lua.h */ @@ -39,7 +39,7 @@ static int math_abs (lua_State *L) { if (lua_isinteger(L, 1)) { lua_Integer n = lua_tointeger(L, 1); - if (n < 0) n = (lua_Integer)(0u - n); + if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n); lua_pushinteger(L, n); } else @@ -184,10 +184,13 @@ static int math_log (lua_State *L) { else { lua_Number base = luaL_checknumber(L, 2); #if !defined(LUA_USE_C89) - if (base == 2.0) res = l_mathop(log2)(x); else + if (base == l_mathop(2.0)) + res = l_mathop(log2)(x); else #endif - if (base == 10.0) res = l_mathop(log10)(x); - else res = l_mathop(log)(x)/l_mathop(log)(base); + if (base == l_mathop(10.0)) + res = l_mathop(log10)(x); + else + res = l_mathop(log)(x)/l_mathop(log)(base); } lua_pushnumber(L, res); return 1; @@ -262,7 +265,7 @@ static int math_random (lua_State *L) { default: return luaL_error(L, "wrong number of arguments"); } /* random integer in the interval [low, up] */ - luaL_argcheck(L, low <= up, 1, "interval is empty"); + luaL_argcheck(L, low <= up, 1, "interval is empty"); luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 1, "interval too large"); r *= (double)(up - low) + 1.0; @@ -273,7 +276,7 @@ static int math_random (lua_State *L) { static int math_randomseed (lua_State *L) { l_srand((unsigned int)(lua_Integer)luaL_checknumber(L, 1)); - (void)rand(); /* discard first value to avoid undesirable correlations */ + (void)l_rand(); /* discard first value to avoid undesirable correlations */ return 0; } @@ -281,9 +284,9 @@ static int math_randomseed (lua_State *L) { static int math_type (lua_State *L) { if (lua_type(L, 1) == LUA_TNUMBER) { if (lua_isinteger(L, 1)) - lua_pushliteral(L, "integer"); + lua_pushliteral(L, "integer"); else - lua_pushliteral(L, "float"); + lua_pushliteral(L, "float"); } else { luaL_checkany(L, 1); diff --git a/source/extern/lua/lmem.c b/source/extern/lua/lmem.c index 0a0476c..0241cc3 100644 --- a/source/extern/lua/lmem.c +++ b/source/extern/lua/lmem.c @@ -1,5 +1,5 @@ /* -** $Id: lmem.c,v 1.91 2015/03/06 19:45:54 roberto Exp $ +** $Id: lmem.c,v 1.91.1.1 2017/04/19 17:20:42 roberto Exp $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ diff --git a/source/extern/lua/lmem.h b/source/extern/lua/lmem.h index 30f4848..357b1e4 100644 --- a/source/extern/lua/lmem.h +++ b/source/extern/lua/lmem.h @@ -1,5 +1,5 @@ /* -** $Id: lmem.h,v 1.43 2014/12/19 17:26:14 roberto Exp $ +** $Id: lmem.h,v 1.43.1.1 2017/04/19 17:20:42 roberto Exp $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ diff --git a/source/extern/lua/loadlib.c b/source/extern/lua/loadlib.c index bbf8f67..45f44d3 100644 --- a/source/extern/lua/loadlib.c +++ b/source/extern/lua/loadlib.c @@ -1,5 +1,5 @@ /* -** $Id: loadlib.c,v 1.126 2015/02/16 13:14:33 roberto Exp $ +** $Id: loadlib.c,v 1.130.1.1 2017/04/19 17:20:42 roberto Exp $ ** Dynamic library loader for Lua ** See Copyright Notice in lua.h ** @@ -25,40 +25,9 @@ /* -** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment -** variables that Lua check to set its paths. -*/ -#if !defined(LUA_PATH_VAR) -#define LUA_PATH_VAR "LUA_PATH" -#endif - -#if !defined(LUA_CPATH_VAR) -#define LUA_CPATH_VAR "LUA_CPATH" -#endif - -#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR - -#define LUA_PATHVARVERSION LUA_PATH_VAR LUA_PATHSUFFIX -#define LUA_CPATHVARVERSION LUA_CPATH_VAR LUA_PATHSUFFIX - -/* -** LUA_PATH_SEP is the character that separates templates in a path. -** LUA_PATH_MARK is the string that marks the substitution points in a -** template. -** LUA_EXEC_DIR in a Windows path is replaced by the executable's -** directory. ** LUA_IGMARK is a mark to ignore all before it when building the ** luaopen_ function name. */ -#if !defined (LUA_PATH_SEP) -#define LUA_PATH_SEP ";" -#endif -#if !defined (LUA_PATH_MARK) -#define LUA_PATH_MARK "?" -#endif -#if !defined (LUA_EXEC_DIR) -#define LUA_EXEC_DIR "!" -#endif #if !defined (LUA_IGMARK) #define LUA_IGMARK "-" #endif @@ -94,7 +63,8 @@ static const int CLIBS = 0; #define LIB_FAIL "open" -#define setprogdir(L) ((void)0) + +#define setprogdir(L) ((void)0) /* @@ -179,7 +149,6 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { #include -#undef setprogdir /* ** optional flags for LoadLibraryEx @@ -189,21 +158,30 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { #endif +#undef setprogdir + + +/* +** Replace in the path (on the top of the stack) any occurrence +** of LUA_EXEC_DIR with the executable's path. +*/ static void setprogdir (lua_State *L) { char buff[MAX_PATH + 1]; char *lb; DWORD nsize = sizeof(buff)/sizeof(char); - DWORD n = GetModuleFileNameA(NULL, buff, nsize); + DWORD n = GetModuleFileNameA(NULL, buff, nsize); /* get exec. name */ if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) luaL_error(L, "unable to get ModuleFileName"); else { - *lb = '\0'; + *lb = '\0'; /* cut name on the last '\\' to get the path */ luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff); lua_remove(L, -2); /* remove original string */ } } + + static void pusherror (lua_State *L) { int error = GetLastError(); char buffer[128]; @@ -272,6 +250,67 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { #endif /* } */ +/* +** {================================================================== +** Set Paths +** =================================================================== +*/ + +/* +** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment +** variables that Lua check to set its paths. +*/ +#if !defined(LUA_PATH_VAR) +#define LUA_PATH_VAR "LUA_PATH" +#endif + +#if !defined(LUA_CPATH_VAR) +#define LUA_CPATH_VAR "LUA_CPATH" +#endif + + +#define AUXMARK "\1" /* auxiliary mark */ + + +/* +** return registry.LUA_NOENV as a boolean +*/ +static int noenv (lua_State *L) { + int b; + lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); + b = lua_toboolean(L, -1); + lua_pop(L, 1); /* remove value */ + return b; +} + + +/* +** Set a path +*/ +static void setpath (lua_State *L, const char *fieldname, + const char *envname, + const char *dft) { + const char *nver = lua_pushfstring(L, "%s%s", envname, LUA_VERSUFFIX); + const char *path = getenv(nver); /* use versioned name */ + if (path == NULL) /* no environment variable? */ + path = getenv(envname); /* try unversioned name */ + if (path == NULL || noenv(L)) /* no environment variable? */ + lua_pushstring(L, dft); /* use default */ + else { + /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ + path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP, + LUA_PATH_SEP AUXMARK LUA_PATH_SEP); + luaL_gsub(L, path, AUXMARK, dft); + lua_remove(L, -2); /* remove result from 1st 'gsub' */ + } + setprogdir(L); + lua_setfield(L, -3, fieldname); /* package[fieldname] = path value */ + lua_pop(L, 1); /* pop versioned variable name */ +} + +/* }================================================================== */ + + /* ** return registry.CLIBS[path] */ @@ -520,7 +559,7 @@ static int searcher_Croot (lua_State *L) { static int searcher_preload (lua_State *L) { const char *name = luaL_checkstring(L, 1); - lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); + lua_getfield(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); if (lua_getfield(L, -1, name) == LUA_TNIL) /* not found? */ lua_pushfstring(L, "\n\tno field package.preload['%s']", name); return 1; @@ -557,9 +596,9 @@ static void findloader (lua_State *L, const char *name) { static int ll_require (lua_State *L) { const char *name = luaL_checkstring(L, 1); - lua_settop(L, 1); /* _LOADED table will be at index 2 */ - lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); - lua_getfield(L, 2, name); /* _LOADED[name] */ + lua_settop(L, 1); /* LOADED table will be at index 2 */ + lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); + lua_getfield(L, 2, name); /* LOADED[name] */ if (lua_toboolean(L, -1)) /* is it there? */ return 1; /* package is already loaded */ /* else must load package */ @@ -569,11 +608,11 @@ static int ll_require (lua_State *L) { lua_insert(L, -2); /* name is 1st argument (before search data) */ lua_call(L, 2, 1); /* run loader to load module */ if (!lua_isnil(L, -1)) /* non-nil return? */ - lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ + lua_setfield(L, 2, name); /* LOADED[name] = returned value */ if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */ lua_pushboolean(L, 1); /* use true as result */ lua_pushvalue(L, -1); /* extra copy to be returned */ - lua_setfield(L, 2, name); /* _LOADED[name] = true */ + lua_setfield(L, 2, name); /* LOADED[name] = true */ } return 1; } @@ -666,41 +705,6 @@ static int ll_seeall (lua_State *L) { -/* auxiliary mark (for internal use) */ -#define AUXMARK "\1" - - -/* -** return registry.LUA_NOENV as a boolean -*/ -static int noenv (lua_State *L) { - int b; - lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); - b = lua_toboolean(L, -1); - lua_pop(L, 1); /* remove value */ - return b; -} - - -static void setpath (lua_State *L, const char *fieldname, const char *envname1, - const char *envname2, const char *def) { - const char *path = getenv(envname1); - if (path == NULL) /* no environment variable? */ - path = getenv(envname2); /* try alternative name */ - if (path == NULL || noenv(L)) /* no environment variable? */ - lua_pushstring(L, def); /* use default */ - else { - /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ - path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP, - LUA_PATH_SEP AUXMARK LUA_PATH_SEP); - luaL_gsub(L, path, AUXMARK, def); - lua_remove(L, -2); - } - setprogdir(L); - lua_setfield(L, -2, fieldname); -} - - static const luaL_Reg pk_funcs[] = { {"loadlib", ll_loadlib}, {"searchpath", ll_searchpath}, @@ -732,7 +736,7 @@ static void createsearcherstable (lua_State *L) { int i; /* create 'searchers' table */ lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0); - /* fill it with pre-defined searchers */ + /* fill it with predefined searchers */ for (i=0; searchers[i] != NULL; i++) { lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */ lua_pushcclosure(L, searchers[i], 1); @@ -764,19 +768,18 @@ LUAMOD_API int luaopen_package (lua_State *L) { createclibstable(L); luaL_newlib(L, pk_funcs); /* create 'package' table */ createsearcherstable(L); - /* set field 'path' */ - setpath(L, "path", LUA_PATHVARVERSION, LUA_PATH_VAR, LUA_PATH_DEFAULT); - /* set field 'cpath' */ - setpath(L, "cpath", LUA_CPATHVARVERSION, LUA_CPATH_VAR, LUA_CPATH_DEFAULT); + /* set paths */ + setpath(L, "path", LUA_PATH_VAR, LUA_PATH_DEFAULT); + setpath(L, "cpath", LUA_CPATH_VAR, LUA_CPATH_DEFAULT); /* store config information */ lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); lua_setfield(L, -2, "config"); /* set field 'loaded' */ - luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); + luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); lua_setfield(L, -2, "loaded"); /* set field 'preload' */ - luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); + luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); lua_setfield(L, -2, "preload"); lua_pushglobaltable(L); lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ diff --git a/source/extern/lua/lobject.c b/source/extern/lua/lobject.c index 6c53b98..355bf58 100644 --- a/source/extern/lua/lobject.c +++ b/source/extern/lua/lobject.c @@ -1,5 +1,5 @@ /* -** $Id: lobject.c,v 2.104 2015/04/11 18:30:08 roberto Exp $ +** $Id: lobject.c,v 2.113.1.1 2017/04/19 17:29:57 roberto Exp $ ** Some generic functions over Lua objects ** See Copyright Notice in lua.h */ @@ -55,9 +55,7 @@ int luaO_int2fb (unsigned int x) { /* converts back */ int luaO_fb2int (int x) { - int e = (x >> 3) & 0x1f; - if (e == 0) return x; - else return ((x & 7) + 8) << (e - 1); + return (x < 8) ? x : ((x & 7) + 8) << ((x >> 3) - 1); } @@ -245,20 +243,59 @@ static lua_Number lua_strx2number (const char *s, char **endptr) { /* }====================================================== */ -static const char *l_str2d (const char *s, lua_Number *result) { +/* maximum length of a numeral */ +#if !defined (L_MAXLENNUM) +#define L_MAXLENNUM 200 +#endif + +static const char *l_str2dloc (const char *s, lua_Number *result, int mode) { char *endptr; - if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */ - return NULL; - else if (strpbrk(s, "xX")) /* hex? */ - *result = lua_strx2number(s, &endptr); - else - *result = lua_str2number(s, &endptr); - if (endptr == s) return NULL; /* nothing recognized */ - while (lisspace(cast_uchar(*endptr))) endptr++; - return (*endptr == '\0' ? endptr : NULL); /* OK if no trailing characters */ + *result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */ + : lua_str2number(s, &endptr); + if (endptr == s) return NULL; /* nothing recognized? */ + while (lisspace(cast_uchar(*endptr))) endptr++; /* skip trailing spaces */ + return (*endptr == '\0') ? endptr : NULL; /* OK if no trailing characters */ } +/* +** Convert string 's' to a Lua number (put in 'result'). Return NULL +** on fail or the address of the ending '\0' on success. +** 'pmode' points to (and 'mode' contains) special things in the string: +** - 'x'/'X' means an hexadecimal numeral +** - 'n'/'N' means 'inf' or 'nan' (which should be rejected) +** - '.' just optimizes the search for the common case (nothing special) +** This function accepts both the current locale or a dot as the radix +** mark. If the conversion fails, it may mean number has a dot but +** locale accepts something else. In that case, the code copies 's' +** to a buffer (because 's' is read-only), changes the dot to the +** current locale radix mark, and tries to convert again. +*/ +static const char *l_str2d (const char *s, lua_Number *result) { + const char *endptr; + const char *pmode = strpbrk(s, ".xXnN"); + int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0; + if (mode == 'n') /* reject 'inf' and 'nan' */ + return NULL; + endptr = l_str2dloc(s, result, mode); /* try to convert */ + if (endptr == NULL) { /* failed? may be a different locale */ + char buff[L_MAXLENNUM + 1]; + const char *pdot = strchr(s, '.'); + if (strlen(s) > L_MAXLENNUM || pdot == NULL) + return NULL; /* string too long or no dot; fail */ + strcpy(buff, s); /* copy string to buffer */ + buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */ + endptr = l_str2dloc(buff, result, mode); /* try again */ + if (endptr != NULL) + endptr = s + (endptr - buff); /* make relative to 's' */ + } + return endptr; +} + + +#define MAXBY10 cast(lua_Unsigned, LUA_MAXINTEGER / 10) +#define MAXLASTD cast_int(LUA_MAXINTEGER % 10) + static const char *l_str2int (const char *s, lua_Integer *result) { lua_Unsigned a = 0; int empty = 1; @@ -275,7 +312,10 @@ static const char *l_str2int (const char *s, lua_Integer *result) { } else { /* decimal */ for (; lisdigit(cast_uchar(*s)); s++) { - a = a * 10 + *s - '0'; + int d = *s - '0'; + if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */ + return NULL; /* do not accept it (as integer) */ + a = a * 10 + d; empty = 0; } } @@ -333,9 +373,9 @@ void luaO_tostring (lua_State *L, StkId obj) { size_t len; lua_assert(ttisnumber(obj)); if (ttisinteger(obj)) - len = lua_integer2str(buff, ivalue(obj)); + len = lua_integer2str(buff, sizeof(buff), ivalue(obj)); else { - len = lua_number2str(buff, fltvalue(obj)); + len = lua_number2str(buff, sizeof(buff), fltvalue(obj)); #if !defined(LUA_COMPAT_FLOATSTRING) if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */ buff[len++] = lua_getlocaledecpoint(); @@ -348,27 +388,29 @@ void luaO_tostring (lua_State *L, StkId obj) { static void pushstr (lua_State *L, const char *str, size_t l) { - setsvalue2s(L, L->top++, luaS_newlstr(L, str, l)); + setsvalue2s(L, L->top, luaS_newlstr(L, str, l)); + luaD_inctop(L); } -/* this function handles only '%d', '%c', '%f', '%p', and '%s' - conventional formats, plus Lua-specific '%I' and '%U' */ +/* +** this function handles only '%d', '%c', '%f', '%p', and '%s' + conventional formats, plus Lua-specific '%I' and '%U' +*/ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { int n = 0; for (;;) { const char *e = strchr(fmt, '%'); if (e == NULL) break; - luaD_checkstack(L, 2); /* fmt + item */ pushstr(L, fmt, e - fmt); switch (*(e+1)) { - case 's': { + case 's': { /* zero-terminated string */ const char *s = va_arg(argp, char *); if (s == NULL) s = "(null)"; pushstr(L, s, strlen(s)); break; } - case 'c': { + case 'c': { /* an 'int' as a character */ char buff = cast(char, va_arg(argp, int)); if (lisprint(cast_uchar(buff))) pushstr(L, &buff, 1); @@ -376,28 +418,29 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { luaO_pushfstring(L, "<\\%d>", cast_uchar(buff)); break; } - case 'd': { - setivalue(L->top++, va_arg(argp, int)); + case 'd': { /* an 'int' */ + setivalue(L->top, va_arg(argp, int)); + goto top2str; + } + case 'I': { /* a 'lua_Integer' */ + setivalue(L->top, cast(lua_Integer, va_arg(argp, l_uacInt))); + goto top2str; + } + case 'f': { /* a 'lua_Number' */ + setfltvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); + top2str: /* convert the top element to a string */ + luaD_inctop(L); luaO_tostring(L, L->top - 1); break; } - case 'I': { - setivalue(L->top++, cast(lua_Integer, va_arg(argp, l_uacInt))); - luaO_tostring(L, L->top - 1); - break; - } - case 'f': { - setfltvalue(L->top++, cast_num(va_arg(argp, l_uacNumber))); - luaO_tostring(L, L->top - 1); - break; - } - case 'p': { + case 'p': { /* a pointer */ char buff[4*sizeof(void *) + 8]; /* should be enough space for a '%p' */ - int l = sprintf(buff, "%p", va_arg(argp, void *)); + void *p = va_arg(argp, void *); + int l = lua_pointer2str(buff, sizeof(buff), p); pushstr(L, buff, l); break; } - case 'U': { + case 'U': { /* an 'int' as a UTF-8 sequence */ char buff[UTF8BUFFSZ]; int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long))); pushstr(L, buff + UTF8BUFFSZ - l, l); diff --git a/source/extern/lua/lobject.h b/source/extern/lua/lobject.h index 9230b7a..2408861 100644 --- a/source/extern/lua/lobject.h +++ b/source/extern/lua/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 2.111 2015/06/09 14:21:42 roberto Exp $ +** $Id: lobject.h,v 2.117.1.1 2017/04/19 17:39:34 roberto Exp $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -19,8 +19,8 @@ /* ** Extra tags for non-values */ -#define LUA_TPROTO LUA_NUMTAGS -#define LUA_TDEADKEY (LUA_NUMTAGS+1) +#define LUA_TPROTO LUA_NUMTAGS /* function prototypes */ +#define LUA_TDEADKEY (LUA_NUMTAGS+1) /* removed keys in tables */ /* ** number of all possible tags (including LUA_TNONE but excluding DEADKEY) @@ -88,22 +88,32 @@ struct GCObject { -/* -** Union of all Lua values -*/ -typedef union Value Value; - - - /* ** Tagged Values. This is the basic representation of values in Lua, ** an actual value plus a tag with its type. */ +/* +** Union of all Lua values +*/ +typedef union Value { + GCObject *gc; /* collectable objects */ + void *p; /* light userdata */ + int b; /* booleans */ + lua_CFunction f; /* light C functions */ + lua_Integer i; /* integer numbers */ + lua_Number n; /* float numbers */ +} Value; + + #define TValuefields Value value_; int tt_ -typedef struct lua_TValue TValue; + +typedef struct lua_TValue { + TValuefields; +} TValue; + /* macro defining a nil value */ @@ -177,9 +187,9 @@ typedef struct lua_TValue TValue; /* Macros for internal tests */ #define righttt(obj) (ttype(obj) == gcvalue(obj)->tt) -#define checkliveness(g,obj) \ +#define checkliveness(L,obj) \ lua_longassert(!iscollectable(obj) || \ - (righttt(obj) && !isdead(g,gcvalue(obj)))) + (righttt(obj) && (L == NULL || !isdead(G(L),gcvalue(obj))))) /* Macros to set values */ @@ -215,32 +225,32 @@ typedef struct lua_TValue TValue; #define setsvalue(L,obj,x) \ { TValue *io = (obj); TString *x_ = (x); \ val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \ - checkliveness(G(L),io); } + checkliveness(L,io); } #define setuvalue(L,obj,x) \ { TValue *io = (obj); Udata *x_ = (x); \ val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TUSERDATA)); \ - checkliveness(G(L),io); } + checkliveness(L,io); } #define setthvalue(L,obj,x) \ { TValue *io = (obj); lua_State *x_ = (x); \ val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTHREAD)); \ - checkliveness(G(L),io); } + checkliveness(L,io); } #define setclLvalue(L,obj,x) \ { TValue *io = (obj); LClosure *x_ = (x); \ val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TLCL)); \ - checkliveness(G(L),io); } + checkliveness(L,io); } #define setclCvalue(L,obj,x) \ { TValue *io = (obj); CClosure *x_ = (x); \ val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TCCL)); \ - checkliveness(G(L),io); } + checkliveness(L,io); } #define sethvalue(L,obj,x) \ { TValue *io = (obj); Table *x_ = (x); \ val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTABLE)); \ - checkliveness(G(L),io); } + checkliveness(L,io); } #define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY) @@ -248,7 +258,7 @@ typedef struct lua_TValue TValue; #define setobj(L,obj1,obj2) \ { TValue *io1=(obj1); *io1 = *(obj2); \ - (void)L; checkliveness(G(L),io1); } + (void)L; checkliveness(L,io1); } /* @@ -264,12 +274,13 @@ typedef struct lua_TValue TValue; #define setptvalue2s setptvalue /* from table to same table */ #define setobjt2t setobj -/* to table */ -#define setobj2t setobj /* to new object */ #define setobj2n setobj #define setsvalue2n setsvalue +/* to table (define it as an expression to be used in macros) */ +#define setobj2t(L,o1,o2) ((void)L, *(o1)=*(o2), checkliveness(L,(o1))) + @@ -280,21 +291,6 @@ typedef struct lua_TValue TValue; */ -union Value { - GCObject *gc; /* collectable objects */ - void *p; /* light userdata */ - int b; /* booleans */ - lua_CFunction f; /* light C functions */ - lua_Integer i; /* integer numbers */ - lua_Number n; /* float numbers */ -}; - - -struct lua_TValue { - TValuefields; -}; - - typedef TValue *StkId; /* index to stack elements */ @@ -329,9 +325,9 @@ typedef union UTString { ** Get the actual string (array of bytes) from a 'TString'. ** (Access to 'extra' ensures that value is really a 'TString'.) */ -#define getaddrstr(ts) (cast(char *, (ts)) + sizeof(UTString)) #define getstr(ts) \ - check_exp(sizeof((ts)->extra), cast(const char*, getaddrstr(ts))) + check_exp(sizeof((ts)->extra), cast(char *, (ts)) + sizeof(UTString)) + /* get the actual string (array of bytes) from a Lua value */ #define svalue(o) getstr(tsvalue(o)) @@ -375,13 +371,13 @@ typedef union UUdata { #define setuservalue(L,u,o) \ { const TValue *io=(o); Udata *iu = (u); \ iu->user_ = io->value_; iu->ttuv_ = rttype(io); \ - checkliveness(G(L),io); } + checkliveness(L,io); } #define getuservalue(L,u,o) \ { TValue *io=(o); const Udata *iu = (u); \ io->value_ = iu->user_; settt_(io, iu->ttuv_); \ - checkliveness(G(L),io); } + checkliveness(L,io); } /* @@ -419,8 +415,8 @@ typedef struct Proto { int sizelineinfo; int sizep; /* size of 'p' */ int sizelocvars; - int linedefined; - int lastlinedefined; + int linedefined; /* debug information */ + int lastlinedefined; /* debug information */ TValue *k; /* constants used by the function */ Instruction *code; /* opcodes */ struct Proto **p; /* functions defined inside the function */ @@ -489,7 +485,7 @@ typedef union TKey { #define setnodekey(L,key,obj) \ { TKey *k_=(key); const TValue *io_=(obj); \ k_->nk.value_ = io_->value_; k_->nk.tt_ = io_->tt_; \ - (void)L; checkliveness(G(L),io_); } + (void)L; checkliveness(L,io_); } typedef struct Node { diff --git a/source/extern/lua/lopcodes.c b/source/extern/lua/lopcodes.c index a1cbef8..5ca3eb2 100644 --- a/source/extern/lua/lopcodes.c +++ b/source/extern/lua/lopcodes.c @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.c,v 1.55 2015/01/05 13:48:33 roberto Exp $ +** $Id: lopcodes.c,v 1.55.1.1 2017/04/19 17:20:42 roberto Exp $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ diff --git a/source/extern/lua/lopcodes.h b/source/extern/lua/lopcodes.h index 864b8e4..6feaa1c 100644 --- a/source/extern/lua/lopcodes.h +++ b/source/extern/lua/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.148 2014/10/25 11:50:46 roberto Exp $ +** $Id: lopcodes.h,v 1.149.1.1 2017/04/19 17:20:42 roberto Exp $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -139,7 +139,9 @@ enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ /* gets the index of the constant */ #define INDEXK(r) ((int)(r) & ~BITRK) +#if !defined(MAXINDEXRK) /* (for debugging only) */ #define MAXINDEXRK (BITRK - 1) +#endif /* code a constant index as a RK value */ #define RKASK(x) ((x) | BITRK) diff --git a/source/extern/lua/loslib.c b/source/extern/lua/loslib.c index cb8a3c3..de590c6 100644 --- a/source/extern/lua/loslib.c +++ b/source/extern/lua/loslib.c @@ -1,5 +1,5 @@ /* -** $Id: loslib.c,v 1.57 2015/04/10 17:41:04 roberto Exp $ +** $Id: loslib.c,v 1.65.1.1 2017/04/19 17:29:57 roberto Exp $ ** Standard Operating System library ** See Copyright Notice in lua.h */ @@ -24,18 +24,29 @@ /* ** {================================================================== -** list of valid conversion specifiers for the 'strftime' function +** List of valid conversion specifiers for the 'strftime' function; +** options are grouped by length; group of length 2 start with '||'. ** =================================================================== */ #if !defined(LUA_STRFTIMEOPTIONS) /* { */ -#if defined(LUA_USE_C89) -#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" } +/* options for ANSI C 89 (only 1-char options) */ +#define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%" + +/* options for ISO C 99 and POSIX */ +#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \ + "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" /* two-char options */ + +/* options for Windows */ +#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \ + "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" /* two-char options */ + +#if defined(LUA_USE_WINDOWS) +#define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN +#elif defined(LUA_USE_C89) +#define LUA_STRFTIMEOPTIONS L_STRFTIMEC89 #else /* C99 specification */ -#define LUA_STRFTIMEOPTIONS \ - { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "", \ - "E", "cCxXyY", \ - "O", "deHImMSuUVwWy" } +#define LUA_STRFTIMEOPTIONS L_STRFTIMEC99 #endif #endif /* } */ @@ -54,7 +65,12 @@ */ #define l_timet lua_Integer #define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t)) -#define l_checktime(L,a) ((time_t)luaL_checkinteger(L,a)) + +static time_t l_checktime (lua_State *L, int arg) { + lua_Integer t = luaL_checkinteger(L, arg); + luaL_argcheck(L, (time_t)t == t, arg, "time out-of-bounds"); + return (time_t)t; +} #endif /* } */ @@ -190,6 +206,23 @@ static void setboolfield (lua_State *L, const char *key, int value) { lua_setfield(L, -2, key); } + +/* +** Set all fields from structure 'tm' in the table on top of the stack +*/ +static void setallfields (lua_State *L, struct tm *stm) { + setfield(L, "sec", stm->tm_sec); + setfield(L, "min", stm->tm_min); + setfield(L, "hour", stm->tm_hour); + setfield(L, "day", stm->tm_mday); + setfield(L, "month", stm->tm_mon + 1); + setfield(L, "year", stm->tm_year + 1900); + setfield(L, "wday", stm->tm_wday + 1); + setfield(L, "yday", stm->tm_yday + 1); + setboolfield(L, "isdst", stm->tm_isdst); +} + + static int getboolfield (lua_State *L, const char *key) { int res; res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1); @@ -198,36 +231,43 @@ static int getboolfield (lua_State *L, const char *key) { } -static int getfield (lua_State *L, const char *key, int d) { - int res, isnum; - lua_getfield(L, -1, key); - res = (int)lua_tointegerx(L, -1, &isnum); - if (!isnum) { - if (d < 0) +/* maximum value for date fields (to avoid arithmetic overflows with 'int') */ +#if !defined(L_MAXDATEFIELD) +#define L_MAXDATEFIELD (INT_MAX / 2) +#endif + +static int getfield (lua_State *L, const char *key, int d, int delta) { + int isnum; + int t = lua_getfield(L, -1, key); /* get field and its type */ + lua_Integer res = lua_tointegerx(L, -1, &isnum); + if (!isnum) { /* field is not an integer? */ + if (t != LUA_TNIL) /* some other value? */ + return luaL_error(L, "field '%s' is not an integer", key); + else if (d < 0) /* absent field; no default? */ return luaL_error(L, "field '%s' missing in date table", key); res = d; } + else { + if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD)) + return luaL_error(L, "field '%s' is out-of-bound", key); + res -= delta; + } lua_pop(L, 1); - return res; + return (int)res; } -static const char *checkoption (lua_State *L, const char *conv, char *buff) { - static const char *const options[] = LUA_STRFTIMEOPTIONS; - unsigned int i; - for (i = 0; i < sizeof(options)/sizeof(options[0]); i += 2) { - if (*conv != '\0' && strchr(options[i], *conv) != NULL) { - buff[1] = *conv; - if (*options[i + 1] == '\0') { /* one-char conversion specifier? */ - buff[2] = '\0'; /* end buffer */ - return conv + 1; - } - else if (*(conv + 1) != '\0' && - strchr(options[i + 1], *(conv + 1)) != NULL) { - buff[2] = *(conv + 1); /* valid two-char conversion specifier */ - buff[3] = '\0'; /* end buffer */ - return conv + 2; - } +static const char *checkoption (lua_State *L, const char *conv, + ptrdiff_t convlen, char *buff) { + const char *option = LUA_STRFTIMEOPTIONS; + int oplen = 1; /* length of options being checked */ + for (; *option != '\0' && oplen <= convlen; option += oplen) { + if (*option == '|') /* next block? */ + oplen++; /* will check options with next length (+1) */ + else if (memcmp(conv, option, oplen) == 0) { /* match? */ + memcpy(buff, conv, oplen); /* copy valid option to buffer */ + buff[oplen] = '\0'; + return conv + oplen; /* return next item */ } } luaL_argerror(L, 1, @@ -236,9 +276,15 @@ static const char *checkoption (lua_State *L, const char *conv, char *buff) { } +/* maximum size for an individual 'strftime' item */ +#define SIZETIMEFMT 250 + + static int os_date (lua_State *L) { - const char *s = luaL_optstring(L, 1, "%c"); + size_t slen; + const char *s = luaL_optlstring(L, 1, "%c", &slen); time_t t = luaL_opt(L, l_checktime, 2, time(NULL)); + const char *se = s + slen; /* 's' end */ struct tm tmr, *stm; if (*s == '!') { /* UTC? */ stm = l_gmtime(&t, &tmr); @@ -247,33 +293,27 @@ static int os_date (lua_State *L) { else stm = l_localtime(&t, &tmr); if (stm == NULL) /* invalid date? */ - lua_pushnil(L); - else if (strcmp(s, "*t") == 0) { + return luaL_error(L, + "time result cannot be represented in this installation"); + if (strcmp(s, "*t") == 0) { lua_createtable(L, 0, 9); /* 9 = number of fields */ - setfield(L, "sec", stm->tm_sec); - setfield(L, "min", stm->tm_min); - setfield(L, "hour", stm->tm_hour); - setfield(L, "day", stm->tm_mday); - setfield(L, "month", stm->tm_mon+1); - setfield(L, "year", stm->tm_year+1900); - setfield(L, "wday", stm->tm_wday+1); - setfield(L, "yday", stm->tm_yday+1); - setboolfield(L, "isdst", stm->tm_isdst); + setallfields(L, stm); } else { - char cc[4]; + char cc[4]; /* buffer for individual conversion specifiers */ luaL_Buffer b; cc[0] = '%'; luaL_buffinit(L, &b); - while (*s) { - if (*s != '%') /* no conversion specifier? */ + while (s < se) { + if (*s != '%') /* not a conversion specifier? */ luaL_addchar(&b, *s++); else { size_t reslen; - char buff[200]; /* should be big enough for any conversion result */ - s = checkoption(L, s + 1, cc); - reslen = strftime(buff, sizeof(buff), cc, stm); - luaL_addlstring(&b, buff, reslen); + char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT); + s++; /* skip '%' */ + s = checkoption(L, s, se - s, cc + 1); /* copy specifier to 'cc' */ + reslen = strftime(buff, SIZETIMEFMT, cc, stm); + luaL_addsize(&b, reslen); } } luaL_pushresult(&b); @@ -290,21 +330,20 @@ static int os_time (lua_State *L) { struct tm ts; luaL_checktype(L, 1, LUA_TTABLE); lua_settop(L, 1); /* make sure table is at the top */ - ts.tm_sec = getfield(L, "sec", 0); - ts.tm_min = getfield(L, "min", 0); - ts.tm_hour = getfield(L, "hour", 12); - ts.tm_mday = getfield(L, "day", -1); - ts.tm_mon = getfield(L, "month", -1) - 1; - ts.tm_year = getfield(L, "year", -1) - 1900; + ts.tm_sec = getfield(L, "sec", 0, 0); + ts.tm_min = getfield(L, "min", 0, 0); + ts.tm_hour = getfield(L, "hour", 12, 0); + ts.tm_mday = getfield(L, "day", -1, 0); + ts.tm_mon = getfield(L, "month", -1, 1); + ts.tm_year = getfield(L, "year", -1, 1900); ts.tm_isdst = getboolfield(L, "isdst"); t = mktime(&ts); + setallfields(L, &ts); /* update fields with normalized values */ } - if (t != (time_t)(l_timet)t) - luaL_error(L, "time result cannot be represented in this Lua installation"); - else if (t == (time_t)(-1)) - lua_pushnil(L); - else - l_pushtime(L, t); + if (t != (time_t)(l_timet)t || t == (time_t)(-1)) + return luaL_error(L, + "time result cannot be represented in this installation"); + l_pushtime(L, t); return 1; } diff --git a/source/extern/lua/lparser.c b/source/extern/lua/lparser.c index 9a54dfc..2f41e00 100644 --- a/source/extern/lua/lparser.c +++ b/source/extern/lua/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 2.147 2014/12/27 20:31:43 roberto Exp $ +** $Id: lparser.c,v 2.155.1.2 2017/04/29 18:11:40 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -164,7 +164,8 @@ static int registerlocalvar (LexState *ls, TString *varname) { int oldsize = f->sizelocvars; luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, LocVar, SHRT_MAX, "local variables"); - while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; + while (oldsize < f->sizelocvars) + f->locvars[oldsize++].varname = NULL; f->locvars[fs->nlocvars].varname = varname; luaC_objbarrier(ls->L, f, varname); return fs->nlocvars++; @@ -230,7 +231,8 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) { checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues, Upvaldesc, MAXUPVAL, "upvalues"); - while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL; + while (oldsize < f->sizeupvalues) + f->upvalues[oldsize++].name = NULL; f->upvalues[fs->nups].instack = (v->k == VLOCAL); f->upvalues[fs->nups].idx = cast_byte(v->u.info); f->upvalues[fs->nups].name = name; @@ -255,7 +257,8 @@ static int searchvar (FuncState *fs, TString *n) { */ static void markupval (FuncState *fs, int level) { BlockCnt *bl = fs->bl; - while (bl->nactvar > level) bl = bl->previous; + while (bl->nactvar > level) + bl = bl->previous; bl->upval = 1; } @@ -264,27 +267,26 @@ static void markupval (FuncState *fs, int level) { Find variable with given name 'n'. If it is an upvalue, add this upvalue into all intermediate functions. */ -static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { +static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { if (fs == NULL) /* no more levels? */ - return VVOID; /* default is global */ + init_exp(var, VVOID, 0); /* default is global */ else { int v = searchvar(fs, n); /* look up locals at current level */ if (v >= 0) { /* found? */ init_exp(var, VLOCAL, v); /* variable is local */ if (!base) markupval(fs, v); /* local will be used as an upval */ - return VLOCAL; } else { /* not found as local at current level; try upvalues */ int idx = searchupvalue(fs, n); /* try existing upvalues */ if (idx < 0) { /* not found? */ - if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */ - return VVOID; /* not found; is a global */ + singlevaraux(fs->prev, n, var, 0); /* try upper levels */ + if (var->k == VVOID) /* not found? */ + return; /* it is a global */ /* else was LOCAL or UPVAL */ idx = newupvalue(fs, n, var); /* will be a new upvalue */ } - init_exp(var, VUPVAL, idx); - return VUPVAL; + init_exp(var, VUPVAL, idx); /* new or old upvalue */ } } } @@ -293,10 +295,11 @@ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { static void singlevar (LexState *ls, expdesc *var) { TString *varname = str_checkname(ls); FuncState *fs = ls->fs; - if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */ + singlevaraux(fs, varname, var, 1); + if (var->k == VVOID) { /* global name? */ expdesc key; singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ - lua_assert(var->k == VLOCAL || var->k == VUPVAL); + lua_assert(var->k != VVOID); /* this one must exist */ codestring(ls, &key, varname); /* key is variable name */ luaK_indexed(fs, var, &key); /* env[varname] */ } @@ -320,6 +323,8 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { luaK_nil(fs, reg, extra); } } + if (nexps > nvars) + ls->fs->freereg -= nexps - nvars; /* remove extra values */ } @@ -499,7 +504,8 @@ static Proto *addprototype (LexState *ls) { if (fs->np >= f->sizep) { int oldsize = f->sizep; luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions"); - while (oldsize < f->sizep) f->p[oldsize++] = NULL; + while (oldsize < f->sizep) + f->p[oldsize++] = NULL; } f->p[fs->np++] = clp = luaF_newproto(L); luaC_objbarrier(L, f, clp); @@ -538,6 +544,7 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { fs->bl = NULL; f = fs->f; f->source = ls->source; + luaC_objbarrier(ls->L, f, f->source); f->maxstacksize = 2; /* registers 0/1 are always valid */ enterblock(fs, bl, 0); } @@ -760,7 +767,7 @@ static void parlist (LexState *ls) { } case TK_DOTS: { /* param -> '...' */ luaX_next(ls); - f->is_vararg = 1; + f->is_vararg = 1; /* declared vararg */ break; } default: luaX_syntaxerror(ls, " or '...' expected"); @@ -1155,11 +1162,8 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { int nexps; checknext(ls, '='); nexps = explist(ls, &e); - if (nexps != nvars) { + if (nexps != nvars) adjust_assign(ls, nvars, nexps, &e); - if (nexps > nvars) - ls->fs->freereg -= nexps - nvars; /* remove extra values */ - } else { luaK_setoneret(ls->fs, &e); /* close last expression */ luaK_storevar(ls->fs, &lh->v, &e); @@ -1225,7 +1229,7 @@ static void labelstat (LexState *ls, TString *label, int line) { checkrepeated(fs, ll, label); /* check for repeated labels */ checknext(ls, TK_DBCOLON); /* skip double colon */ /* create new entry for this label */ - l = newlabelentry(ls, ll, label, line, fs->pc); + l = newlabelentry(ls, ll, label, line, luaK_getlabel(fs)); skipnoopstat(ls); /* skip other no-op statements */ if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */ /* assume that locals are already out of scope */ @@ -1389,7 +1393,7 @@ static void test_then_block (LexState *ls, int *escapelist) { luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ enterblock(fs, &bl, 0); /* must enter block before 'goto' */ gotostat(ls, v.t); /* handle goto/break */ - skipnoopstat(ls); /* skip other no-op statements */ + while (testnext(ls, ';')) {} /* skip colons */ if (block_follow(ls, 0)) { /* 'goto' is the entire block? */ leaveblock(fs); return; /* and that is it */ @@ -1493,7 +1497,7 @@ static void exprstat (LexState *ls) { } else { /* stat -> func */ check_condition(ls, v.v.k == VCALL, "syntax error"); - SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ + SETARG_C(getinstruction(fs, &v.v), 1); /* call statement uses no results */ } } @@ -1510,8 +1514,8 @@ static void retstat (LexState *ls) { if (hasmultret(e.k)) { luaK_setmultret(fs, &e); if (e.k == VCALL && nret == 1) { /* tail call? */ - SET_OPCODE(getcode(fs,&e), OP_TAILCALL); - lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); + SET_OPCODE(getinstruction(fs,&e), OP_TAILCALL); + lua_assert(GETARG_A(getinstruction(fs,&e)) == fs->nactvar); } first = fs->nactvar; nret = LUA_MULTRET; /* return all values */ @@ -1610,9 +1614,10 @@ static void mainfunc (LexState *ls, FuncState *fs) { BlockCnt bl; expdesc v; open_func(ls, fs, &bl); - fs->f->is_vararg = 1; /* main function is always vararg */ + fs->f->is_vararg = 1; /* main function is always declared vararg */ init_exp(&v, VLOCAL, 0); /* create and... */ newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ + luaC_objbarrier(ls->L, fs->f, ls->envn); luaX_next(ls); /* read first token */ statlist(ls); /* parse main body */ check(ls, TK_EOS); @@ -1626,11 +1631,12 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, FuncState funcstate; LClosure *cl = luaF_newLclosure(L, 1); /* create main closure */ setclLvalue(L, L->top, cl); /* anchor it (to avoid being collected) */ - incr_top(L); + luaD_inctop(L); lexstate.h = luaH_new(L); /* create table for scanner */ sethvalue(L, L->top, lexstate.h); /* anchor it */ - incr_top(L); + luaD_inctop(L); funcstate.f = cl->p = luaF_newproto(L); + luaC_objbarrier(L, cl, cl->p); funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ lua_assert(iswhite(funcstate.f)); /* do not need barrier here */ lexstate.buff = buff; diff --git a/source/extern/lua/lparser.h b/source/extern/lua/lparser.h index 62c50ca..f45b23c 100644 --- a/source/extern/lua/lparser.h +++ b/source/extern/lua/lparser.h @@ -1,5 +1,5 @@ /* -** $Id: lparser.h,v 1.74 2014/10/25 11:50:46 roberto Exp $ +** $Id: lparser.h,v 1.76.1.1 2017/04/19 17:20:42 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -13,25 +13,38 @@ /* -** Expression descriptor +** Expression and variable descriptor. +** Code generation for variables and expressions can be delayed to allow +** optimizations; An 'expdesc' structure describes a potentially-delayed +** variable/expression. It has a description of its "main" value plus a +** list of conditional jumps that can also produce its value (generated +** by short-circuit operators 'and'/'or'). */ +/* kinds of variables/expressions */ typedef enum { - VVOID, /* no value */ - VNIL, - VTRUE, - VFALSE, - VK, /* info = index of constant in 'k' */ - VKFLT, /* nval = numerical float value */ - VKINT, /* nval = numerical integer value */ - VNONRELOC, /* info = result register */ - VLOCAL, /* info = local register */ - VUPVAL, /* info = index of upvalue in 'upvalues' */ - VINDEXED, /* t = table register/upvalue; idx = index R/K */ - VJMP, /* info = instruction pc */ - VRELOCABLE, /* info = instruction pc */ - VCALL, /* info = instruction pc */ - VVARARG /* info = instruction pc */ + VVOID, /* when 'expdesc' describes the last expression a list, + this kind means an empty list (so, no expression) */ + VNIL, /* constant nil */ + VTRUE, /* constant true */ + VFALSE, /* constant false */ + VK, /* constant in 'k'; info = index of constant in 'k' */ + VKFLT, /* floating constant; nval = numerical float value */ + VKINT, /* integer constant; nval = numerical integer value */ + VNONRELOC, /* expression has its value in a fixed register; + info = result register */ + VLOCAL, /* local variable; info = local register */ + VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ + VINDEXED, /* indexed variable; + ind.vt = whether 't' is register or upvalue; + ind.t = table register or upvalue; + ind.idx = key's R/K index */ + VJMP, /* expression is a test/comparison; + info = pc of corresponding jump instruction */ + VRELOCABLE, /* expression can put result in any register; + info = instruction pc */ + VCALL, /* expression is a function call; info = instruction pc */ + VVARARG /* vararg expression; info = instruction pc */ } expkind; @@ -41,14 +54,14 @@ typedef enum { typedef struct expdesc { expkind k; union { + lua_Integer ival; /* for VKINT */ + lua_Number nval; /* for VKFLT */ + int info; /* for generic use */ struct { /* for indexed variables (VINDEXED) */ short idx; /* index (R/K) */ lu_byte t; /* table (register or upvalue) */ lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */ } ind; - int info; /* for generic use */ - lua_Number nval; /* for VKFLT */ - lua_Integer ival; /* for VKINT */ } u; int t; /* patch list of 'exit when true' */ int f; /* patch list of 'exit when false' */ diff --git a/source/extern/lua/lprefix.h b/source/extern/lua/lprefix.h index 02daa83..9a749a3 100644 --- a/source/extern/lua/lprefix.h +++ b/source/extern/lua/lprefix.h @@ -1,5 +1,5 @@ /* -** $Id: lprefix.h,v 1.2 2014/12/29 16:54:13 roberto Exp $ +** $Id: lprefix.h,v 1.2.1.1 2017/04/19 17:20:42 roberto Exp $ ** Definitions for Lua code that must come before any other header file ** See Copyright Notice in lua.h */ diff --git a/source/extern/lua/lstate.c b/source/extern/lua/lstate.c index 12e51d2..c1a7664 100644 --- a/source/extern/lua/lstate.c +++ b/source/extern/lua/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 2.128 2015/03/04 13:31:21 roberto Exp $ +** $Id: lstate.c,v 2.133.1.1 2017/04/19 17:39:34 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ @@ -76,7 +76,7 @@ typedef struct LG { */ #define addbuff(b,p,e) \ { size_t t = cast(size_t, e); \ - memcpy(buff + p, &t, sizeof(t)); p += sizeof(t); } + memcpy(b + p, &t, sizeof(t)); p += sizeof(t); } static unsigned int makeseed (lua_State *L) { char buff[4 * sizeof(size_t)]; @@ -93,10 +93,14 @@ static unsigned int makeseed (lua_State *L) { /* ** set GCdebt to a new value keeping the value (totalbytes + GCdebt) -** invariant +** invariant (and avoiding underflows in 'totalbytes') */ void luaE_setdebt (global_State *g, l_mem debt) { - g->totalbytes -= (debt - g->GCdebt); + l_mem tb = gettotalbytes(g); + lua_assert(tb > 0); + if (debt < tb - MAX_LMEM) + debt = tb - MAX_LMEM; /* will make 'totalbytes == MAX_LMEM' */ + g->totalbytes = tb - debt; g->GCdebt = debt; } @@ -107,6 +111,7 @@ CallInfo *luaE_extendCI (lua_State *L) { L->ci->next = ci; ci->previous = L->ci; ci->next = NULL; + L->nci++; return ci; } @@ -121,6 +126,7 @@ void luaE_freeCI (lua_State *L) { while ((ci = next) != NULL) { next = ci->next; luaM_free(L, ci); + L->nci--; } } @@ -130,13 +136,14 @@ void luaE_freeCI (lua_State *L) { */ void luaE_shrinkCI (lua_State *L) { CallInfo *ci = L->ci; - while (ci->next != NULL) { /* while there is 'next' */ - CallInfo *next2 = ci->next->next; /* next's next */ - if (next2 == NULL) break; - luaM_free(L, ci->next); /* remove next */ + CallInfo *next2; /* next's next */ + /* while there are two nexts */ + while (ci->next != NULL && (next2 = ci->next->next) != NULL) { + luaM_free(L, ci->next); /* free next */ + L->nci--; ci->next = next2; /* remove 'next' from the list */ next2->previous = ci; - ci = next2; + ci = next2; /* keep next's next */ } } @@ -166,6 +173,7 @@ static void freestack (lua_State *L) { return; /* stack not completely built yet */ L->ci = &L->base_ci; /* free the entire 'ci' list */ luaE_freeCI(L); + lua_assert(L->nci == 0); luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ } @@ -214,6 +222,7 @@ static void preinit_thread (lua_State *L, global_State *g) { G(L) = g; L->stack = NULL; L->ci = NULL; + L->nci = 0; L->stacksize = 0; L->twups = L; /* thread has no upvalues */ L->errorJmp = NULL; @@ -237,7 +246,6 @@ static void close_state (lua_State *L) { if (g->version) /* closing a fully built state? */ luai_userstateclose(L); luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); - luaZ_freebuffer(L, &g->buff); freestack(L); lua_assert(gettotalbytes(g) == sizeof(LG)); (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ @@ -306,7 +314,6 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { g->strt.size = g->strt.nuse = 0; g->strt.hash = NULL; setnilvalue(&g->l_registry); - luaZ_initbuffer(L, &g->buff); g->panic = NULL; g->version = NULL; g->gcstate = GCSpause; diff --git a/source/extern/lua/lstate.h b/source/extern/lua/lstate.h index eefc217..56b3741 100644 --- a/source/extern/lua/lstate.h +++ b/source/extern/lua/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 2.122 2015/06/01 16:34:37 roberto Exp $ +** $Id: lstate.h,v 2.133.1.1 2017/04/19 17:39:34 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ @@ -23,9 +23,27 @@ ** ** 'allgc': all objects not marked for finalization; ** 'finobj': all objects marked for finalization; -** 'tobefnz': all objects ready to be finalized; +** 'tobefnz': all objects ready to be finalized; ** 'fixedgc': all objects that are not to be collected (currently ** only small strings, such as reserved words). +** +** Moreover, there is another set of lists that control gray objects. +** These lists are linked by fields 'gclist'. (All objects that +** can become gray have such a field. The field is not the same +** in all objects, but it always has this name.) Any gray object +** must belong to one of these lists, and all objects in these lists +** must be gray: +** +** 'gray': regular gray objects, still waiting to be visited. +** 'grayagain': objects that must be revisited at the atomic phase. +** That includes +** - black objects got in a write barrier; +** - all kinds of weak tables during propagation phase; +** - all threads. +** 'weak': tables with weak values to be cleared; +** 'ephemeron': ephemeron tables with white->white entries; +** 'allweak': tables with weak keys and/or weak values to be cleared. +** The last three lists are used only during the atomic phase. */ @@ -33,6 +51,15 @@ struct lua_longjmp; /* defined in ldo.c */ +/* +** Atomic type (relative to signals) to better ensure that 'lua_sethook' +** is thread safe +*/ +#if !defined(l_signalT) +#include +#define l_signalT sig_atomic_t +#endif + /* extra stack space to handle TM calls and some other extras */ #define EXTRA_STACK 5 @@ -57,7 +84,7 @@ typedef struct stringtable { ** Information about a call. ** When a thread yields, 'func' is adjusted to pretend that the ** top function has only the yielded values in its stack; in that -** case, the actual 'func' value is saved in field 'extra'. +** case, the actual 'func' value is saved in field 'extra'. ** When a function calls another with a continuation, 'extra' keeps ** the function index so that, in case of errors, the continuation ** function can be called with the correct top. @@ -79,7 +106,7 @@ typedef struct CallInfo { } u; ptrdiff_t extra; short nresults; /* expected number of results from this function */ - lu_byte callstatus; + unsigned short callstatus; } CallInfo; @@ -89,12 +116,13 @@ typedef struct CallInfo { #define CIST_OAH (1<<0) /* original value of 'allowhook' */ #define CIST_LUA (1<<1) /* call is running a Lua function */ #define CIST_HOOKED (1<<2) /* call is running a debug hook */ -#define CIST_REENTRY (1<<3) /* call is running on same invocation of - luaV_execute of previous call */ +#define CIST_FRESH (1<<3) /* call is running on a fresh invocation + of luaV_execute */ #define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ #define CIST_TAIL (1<<5) /* call was tail called */ #define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ #define CIST_LEQ (1<<7) /* using __lt for __le */ +#define CIST_FIN (1<<8) /* call is running a finalizer */ #define isLua(ci) ((ci)->callstatus & CIST_LUA) @@ -109,7 +137,7 @@ typedef struct CallInfo { typedef struct global_State { lua_Alloc frealloc; /* function to reallocate memory */ void *ud; /* auxiliary data to 'frealloc' */ - lu_mem totalbytes; /* number of bytes currently allocated - GCdebt */ + l_mem totalbytes; /* number of bytes currently allocated - GCdebt */ l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ lu_mem GCmemtrav; /* memory traversed by the GC */ lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ @@ -131,7 +159,6 @@ typedef struct global_State { GCObject *tobefnz; /* list of userdata to be GC */ GCObject *fixedgc; /* list of objects not to be collected */ struct lua_State *twups; /* list of threads with open upvalues */ - Mbuffer buff; /* temporary buffer for string concatenation */ unsigned int gcfinnum; /* number of finalizers to call in each GC step */ int gcpause; /* size of pause between successive GCs */ int gcstepmul; /* GC 'granularity' */ @@ -141,7 +168,7 @@ typedef struct global_State { TString *memerrmsg; /* memory-error message */ TString *tmname[TM_N]; /* array with tag-method names */ struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ - TString *strcache[STRCACHE_SIZE][1]; /* cache for strings in API */ + TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */ } global_State; @@ -150,6 +177,7 @@ typedef struct global_State { */ struct lua_State { CommonHeader; + unsigned short nci; /* number of items in 'ci' list */ lu_byte status; StkId top; /* first free slot in the stack */ global_State *l_G; @@ -162,14 +190,14 @@ struct lua_State { struct lua_State *twups; /* list of threads with open upvalues */ struct lua_longjmp *errorJmp; /* current error recover point */ CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ - lua_Hook hook; + volatile lua_Hook hook; ptrdiff_t errfunc; /* current error handling function (stack index) */ int stacksize; int basehookcount; int hookcount; unsigned short nny; /* number of non-yieldable calls in stack */ unsigned short nCcalls; /* number of nested C calls */ - lu_byte hookmask; + l_signalT hookmask; lu_byte allowhook; }; @@ -212,7 +240,7 @@ union GCUnion { /* actual number of total bytes allocated */ -#define gettotalbytes(g) ((g)->totalbytes + (g)->GCdebt) +#define gettotalbytes(g) cast(lu_mem, (g)->totalbytes + (g)->GCdebt) LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); diff --git a/source/extern/lua/lstring.c b/source/extern/lua/lstring.c index 5e0e3c4..6257f21 100644 --- a/source/extern/lua/lstring.c +++ b/source/extern/lua/lstring.c @@ -1,5 +1,5 @@ /* -** $Id: lstring.c,v 2.49 2015/06/01 16:34:37 roberto Exp $ +** $Id: lstring.c,v 2.56.1.1 2017/04/19 17:20:42 roberto Exp $ ** String table (keeps all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -48,14 +48,23 @@ int luaS_eqlngstr (TString *a, TString *b) { unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { unsigned int h = seed ^ cast(unsigned int, l); - size_t l1; size_t step = (l >> LUAI_HASHLIMIT) + 1; - for (l1 = l; l1 >= step; l1 -= step) - h = h ^ ((h<<5) + (h>>2) + cast_byte(str[l1 - 1])); + for (; l >= step; l -= step) + h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1])); return h; } +unsigned int luaS_hashlongstr (TString *ts) { + lua_assert(ts->tt == LUA_TLNGSTR); + if (ts->extra == 0) { /* no hash? */ + ts->hash = luaS_hash(getstr(ts), ts->u.lnglen, ts->hash); + ts->extra = 1; /* now it has its hash */ + } + return ts->hash; +} + + /* ** resizes the string table */ @@ -92,11 +101,12 @@ void luaS_resize (lua_State *L, int newsize) { ** a non-collectable string.) */ void luaS_clearcache (global_State *g) { - int i; - for (i = 0; i < STRCACHE_SIZE; i++) { - if (iswhite(g->strcache[i][0])) /* will entry be collected? */ - g->strcache[i][0] = g->memerrmsg; /* replace it with something fixed */ - } + int i, j; + for (i = 0; i < STRCACHE_N; i++) + for (j = 0; j < STRCACHE_M; j++) { + if (iswhite(g->strcache[i][j])) /* will entry be collected? */ + g->strcache[i][j] = g->memerrmsg; /* replace it with something fixed */ + } } @@ -105,13 +115,14 @@ void luaS_clearcache (global_State *g) { */ void luaS_init (lua_State *L) { global_State *g = G(L); - int i; + int i, j; luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ /* pre-create memory-error message */ g->memerrmsg = luaS_newliteral(L, MEMERRMSG); luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */ - for (i = 0; i < STRCACHE_SIZE; i++) /* fill cache with valid strings */ - g->strcache[i][0] = g->memerrmsg; + for (i = 0; i < STRCACHE_N; i++) /* fill cache with valid strings */ + for (j = 0; j < STRCACHE_M; j++) + g->strcache[i][j] = g->memerrmsg; } @@ -119,8 +130,7 @@ void luaS_init (lua_State *L) { /* ** creates a new string object */ -static TString *createstrobj (lua_State *L, const char *str, size_t l, - int tag, unsigned int h) { +static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) { TString *ts; GCObject *o; size_t totalsize; /* total size of TString object */ @@ -129,8 +139,14 @@ static TString *createstrobj (lua_State *L, const char *str, size_t l, ts = gco2ts(o); ts->hash = h; ts->extra = 0; - memcpy(getaddrstr(ts), str, l * sizeof(char)); - getaddrstr(ts)[l] = '\0'; /* ending 0 */ + getstr(ts)[l] = '\0'; /* ending 0 */ + return ts; +} + + +TString *luaS_createlngstrobj (lua_State *L, size_t l) { + TString *ts = createstrobj(L, l, LUA_TLNGSTR, G(L)->seed); + ts->u.lnglen = l; return ts; } @@ -153,6 +169,7 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) { global_State *g = G(L); unsigned int h = luaS_hash(str, l, g->seed); TString **list = &g->strt.hash[lmod(h, g->strt.size)]; + lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ for (ts = *list; ts != NULL; ts = ts->u.hnext) { if (l == ts->shrlen && (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { @@ -166,7 +183,8 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) { luaS_resize(L, g->strt.size * 2); list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */ } - ts = createstrobj(L, str, l, LUA_TSHRSTR, h); + ts = createstrobj(L, l, LUA_TSHRSTR, h); + memcpy(getstr(ts), str, l * sizeof(char)); ts->shrlen = cast_byte(l); ts->u.hnext = *list; *list = ts; @@ -183,10 +201,10 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { return internshrstr(L, str, l); else { TString *ts; - if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char)) + if (l >= (MAX_SIZE - sizeof(TString))/sizeof(char)) luaM_toobig(L); - ts = createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed); - ts->u.lnglen = l; + ts = luaS_createlngstrobj(L, l); + memcpy(getstr(ts), str, l * sizeof(char)); return ts; } } @@ -199,15 +217,19 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { ** check hits. */ TString *luaS_new (lua_State *L, const char *str) { - unsigned int i = point2uint(str) % STRCACHE_SIZE; /* hash */ + unsigned int i = point2uint(str) % STRCACHE_N; /* hash */ + int j; TString **p = G(L)->strcache[i]; - if (strcmp(str, getstr(p[0])) == 0) /* hit? */ - return p[0]; /* that it is */ - else { /* normal route */ - TString *s = luaS_newlstr(L, str, strlen(str)); - p[0] = s; - return s; + for (j = 0; j < STRCACHE_M; j++) { + if (strcmp(str, getstr(p[j])) == 0) /* hit? */ + return p[j]; /* that is it */ } + /* normal route */ + for (j = STRCACHE_M - 1; j > 0; j--) + p[j] = p[j - 1]; /* move out last element */ + /* new element is first in the list */ + p[0] = luaS_newlstr(L, str, strlen(str)); + return p[0]; } diff --git a/source/extern/lua/lstring.h b/source/extern/lua/lstring.h index e746f5f..d612abd 100644 --- a/source/extern/lua/lstring.h +++ b/source/extern/lua/lstring.h @@ -1,5 +1,5 @@ /* -** $Id: lstring.h,v 1.59 2015/03/25 13:42:19 roberto Exp $ +** $Id: lstring.h,v 1.61.1.1 2017/04/19 17:20:42 roberto Exp $ ** String table (keep all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -34,6 +34,7 @@ LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); +LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); LUAI_FUNC void luaS_resize (lua_State *L, int newsize); LUAI_FUNC void luaS_clearcache (global_State *g); @@ -42,6 +43,7 @@ LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s); LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); +LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); #endif diff --git a/source/extern/lua/lstrlib.c b/source/extern/lua/lstrlib.c index 19c350d..b4bed7e 100644 --- a/source/extern/lua/lstrlib.c +++ b/source/extern/lua/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.229 2015/05/20 17:39:23 roberto Exp $ +** $Id: lstrlib.c,v 1.254.1.1 2017/04/19 17:29:57 roberto Exp $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -26,7 +27,8 @@ /* ** maximum number of captures that a pattern can do during -** pattern-matching. This limit is arbitrary. +** pattern-matching. This limit is arbitrary, but must fit in +** an unsigned char. */ #if !defined(LUA_MAXCAPTURES) #define LUA_MAXCAPTURES 32 @@ -41,8 +43,10 @@ ** Some sizes are better limited to fit in 'int', but must also fit in ** 'size_t'. (We assume that 'lua_Integer' cannot be smaller than 'int'.) */ +#define MAX_SIZET ((size_t)(~(size_t)0)) + #define MAXSIZE \ - (sizeof(size_t) < sizeof(int) ? (~(size_t)0) : (size_t)(INT_MAX)) + (sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX)) @@ -208,12 +212,12 @@ static int str_dump (lua_State *L) { typedef struct MatchState { - int matchdepth; /* control for recursive depth (to avoid C stack overflow) */ const char *src_init; /* init of source string */ const char *src_end; /* end ('\0') of source string */ const char *p_end; /* end ('\0') of pattern */ lua_State *L; - int level; /* total number of captures (finished or unfinished) */ + int matchdepth; /* control for recursive depth (to avoid C stack overflow) */ + unsigned char level; /* total number of captures (finished or unfinished) */ struct { const char *init; ptrdiff_t len; @@ -584,6 +588,22 @@ static int nospecials (const char *p, size_t l) { } +static void prepstate (MatchState *ms, lua_State *L, + const char *s, size_t ls, const char *p, size_t lp) { + ms->L = L; + ms->matchdepth = MAXCCALLS; + ms->src_init = s; + ms->src_end = s + ls; + ms->p_end = p + lp; +} + + +static void reprepstate (MatchState *ms) { + ms->level = 0; + lua_assert(ms->matchdepth == MAXCCALLS); +} + + static int str_find_aux (lua_State *L, int find) { size_t ls, lp; const char *s = luaL_checklstring(L, 1, &ls); @@ -611,15 +631,10 @@ static int str_find_aux (lua_State *L, int find) { if (anchor) { p++; lp--; /* skip anchor character */ } - ms.L = L; - ms.matchdepth = MAXCCALLS; - ms.src_init = s; - ms.src_end = s + ls; - ms.p_end = p + lp; + prepstate(&ms, L, s, ls, p, lp); do { const char *res; - ms.level = 0; - lua_assert(ms.matchdepth == MAXCCALLS); + reprepstate(&ms); if ((res=match(&ms, s1, p)) != NULL) { if (find) { lua_pushinteger(L, (s1 - s) + 1); /* start */ @@ -646,29 +661,25 @@ static int str_match (lua_State *L) { } +/* state for 'gmatch' */ +typedef struct GMatchState { + const char *src; /* current position */ + const char *p; /* pattern */ + const char *lastmatch; /* end of last match */ + MatchState ms; /* match state */ +} GMatchState; + + static int gmatch_aux (lua_State *L) { - MatchState ms; - size_t ls, lp; - const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); - const char *p = lua_tolstring(L, lua_upvalueindex(2), &lp); + GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3)); const char *src; - ms.L = L; - ms.matchdepth = MAXCCALLS; - ms.src_init = s; - ms.src_end = s+ls; - ms.p_end = p + lp; - for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); - src <= ms.src_end; - src++) { + gm->ms.L = L; + for (src = gm->src; src <= gm->ms.src_end; src++) { const char *e; - ms.level = 0; - lua_assert(ms.matchdepth == MAXCCALLS); - if ((e = match(&ms, src, p)) != NULL) { - lua_Integer newstart = e-s; - if (e == src) newstart++; /* empty match? go at least one position */ - lua_pushinteger(L, newstart); - lua_replace(L, lua_upvalueindex(3)); - return push_captures(&ms, src, e); + reprepstate(&gm->ms); + if ((e = match(&gm->ms, src, gm->p)) != NULL && e != gm->lastmatch) { + gm->src = gm->lastmatch = e; + return push_captures(&gm->ms, src, e); } } return 0; /* not found */ @@ -676,10 +687,14 @@ static int gmatch_aux (lua_State *L) { static int gmatch (lua_State *L) { - luaL_checkstring(L, 1); - luaL_checkstring(L, 2); - lua_settop(L, 2); - lua_pushinteger(L, 0); + size_t ls, lp; + const char *s = luaL_checklstring(L, 1, &ls); + const char *p = luaL_checklstring(L, 2, &lp); + GMatchState *gm; + lua_settop(L, 2); /* keep them on closure to avoid being collected */ + gm = (GMatchState *)lua_newuserdata(L, sizeof(GMatchState)); + prepstate(&gm->ms, L, s, ls, p, lp); + gm->src = s; gm->p = p; gm->lastmatch = NULL; lua_pushcclosure(L, gmatch_aux, 3); return 1; } @@ -746,12 +761,13 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, static int str_gsub (lua_State *L) { size_t srcl, lp; - const char *src = luaL_checklstring(L, 1, &srcl); - const char *p = luaL_checklstring(L, 2, &lp); - int tr = lua_type(L, 3); - lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); + const char *src = luaL_checklstring(L, 1, &srcl); /* subject */ + const char *p = luaL_checklstring(L, 2, &lp); /* pattern */ + const char *lastmatch = NULL; /* end of last match */ + int tr = lua_type(L, 3); /* replacement type */ + lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */ int anchor = (*p == '^'); - lua_Integer n = 0; + lua_Integer n = 0; /* replacement count */ MatchState ms; luaL_Buffer b; luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || @@ -761,25 +777,18 @@ static int str_gsub (lua_State *L) { if (anchor) { p++; lp--; /* skip anchor character */ } - ms.L = L; - ms.matchdepth = MAXCCALLS; - ms.src_init = src; - ms.src_end = src+srcl; - ms.p_end = p + lp; + prepstate(&ms, L, src, srcl, p, lp); while (n < max_s) { const char *e; - ms.level = 0; - lua_assert(ms.matchdepth == MAXCCALLS); - e = match(&ms, src, p); - if (e) { + reprepstate(&ms); /* (re)prepare state for new match */ + if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */ n++; - add_value(&ms, &b, src, e, tr); + add_value(&ms, &b, src, e, tr); /* add replacement to buffer */ + src = lastmatch = e; } - if (e && e>src) /* non empty match? */ - src = e; /* skip it */ - else if (src < ms.src_end) + else if (src < ms.src_end) /* otherwise, skip one character */ luaL_addchar(&b, *src++); - else break; + else break; /* end of subject */ if (anchor) break; } luaL_addlstring(&b, src, ms.src_end-src); @@ -804,7 +813,6 @@ static int str_gsub (lua_State *L) { ** Hexadecimal floating-point formatter */ -#include #include #define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char)) @@ -830,13 +838,13 @@ static lua_Number adddigit (char *buff, int n, lua_Number x) { } -static int num2straux (char *buff, lua_Number x) { - if (x != x || x == HUGE_VAL || x == -HUGE_VAL) /* inf or NaN? */ - return sprintf(buff, LUA_NUMBER_FMT, x); /* equal to '%g' */ +static int num2straux (char *buff, int sz, lua_Number x) { + /* if 'inf' or 'NaN', format it like '%g' */ + if (x != x || x == (lua_Number)HUGE_VAL || x == -(lua_Number)HUGE_VAL) + return l_sprintf(buff, sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)x); else if (x == 0) { /* can be -0... */ - sprintf(buff, LUA_NUMBER_FMT, x); - strcat(buff, "x0p+0"); /* reuses '0/-0' from 'sprintf'... */ - return strlen(buff); + /* create "0" or "-0" followed by exponent */ + return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", (LUAI_UACNUMBER)x); } else { int e; @@ -855,22 +863,23 @@ static int num2straux (char *buff, lua_Number x) { m = adddigit(buff, n++, m * 16); } while (m > 0); } - n += sprintf(buff + n, "p%+d", e); /* add exponent */ + n += l_sprintf(buff + n, sz - n, "p%+d", e); /* add exponent */ + lua_assert(n < sz); return n; } } -static int lua_number2strx (lua_State *L, char *buff, const char *fmt, - lua_Number x) { - int n = num2straux(buff, x); +static int lua_number2strx (lua_State *L, char *buff, int sz, + const char *fmt, lua_Number x) { + int n = num2straux(buff, sz, x); if (fmt[SIZELENMOD] == 'A') { int i; for (i = 0; i < n; i++) buff[i] = toupper(uchar(buff[i])); } else if (fmt[SIZELENMOD] != 'a') - luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented"); + return luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented"); return n; } @@ -879,10 +888,12 @@ static int lua_number2strx (lua_State *L, char *buff, const char *fmt, /* ** Maximum size of each formatted item. This maximum size is produced -** by format('%.99f', minfloat), and is equal to 99 + 2 ('-' and '.') + -** number of decimal digits to represent minfloat. +** by format('%.99f', -maxfloat), and is equal to 99 + 3 ('-', '.', +** and '\0') + number of decimal digits to represent maxfloat (which +** is maximum exponent + 1). (99+3+1 then rounded to 120 for "extra +** expenses", such as locale-dependent stuff) */ -#define MAX_ITEM (120 + l_mathlim(MAX_10_EXP)) +#define MAX_ITEM (120 + l_mathlim(MAX_10_EXP)) /* valid flags in a format specification */ @@ -894,21 +905,19 @@ static int lua_number2strx (lua_State *L, char *buff, const char *fmt, #define MAX_FORMAT 32 -static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { - size_t l; - const char *s = luaL_checklstring(L, arg, &l); +static void addquoted (luaL_Buffer *b, const char *s, size_t len) { luaL_addchar(b, '"'); - while (l--) { + while (len--) { if (*s == '"' || *s == '\\' || *s == '\n') { luaL_addchar(b, '\\'); luaL_addchar(b, *s); } - else if (*s == '\0' || iscntrl(uchar(*s))) { + else if (iscntrl(uchar(*s))) { char buff[10]; if (!isdigit(uchar(*(s+1)))) - sprintf(buff, "\\%d", (int)uchar(*s)); + l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s)); else - sprintf(buff, "\\%03d", (int)uchar(*s)); + l_sprintf(buff, sizeof(buff), "\\%03d", (int)uchar(*s)); luaL_addstring(b, buff); } else @@ -918,6 +927,57 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { luaL_addchar(b, '"'); } + +/* +** Ensures the 'buff' string uses a dot as the radix character. +*/ +static void checkdp (char *buff, int nb) { + if (memchr(buff, '.', nb) == NULL) { /* no dot? */ + char point = lua_getlocaledecpoint(); /* try locale point */ + char *ppoint = (char *)memchr(buff, point, nb); + if (ppoint) *ppoint = '.'; /* change it to a dot */ + } +} + + +static void addliteral (lua_State *L, luaL_Buffer *b, int arg) { + switch (lua_type(L, arg)) { + case LUA_TSTRING: { + size_t len; + const char *s = lua_tolstring(L, arg, &len); + addquoted(b, s, len); + break; + } + case LUA_TNUMBER: { + char *buff = luaL_prepbuffsize(b, MAX_ITEM); + int nb; + if (!lua_isinteger(L, arg)) { /* float? */ + lua_Number n = lua_tonumber(L, arg); /* write as hexa ('%a') */ + nb = lua_number2strx(L, buff, MAX_ITEM, "%" LUA_NUMBER_FRMLEN "a", n); + checkdp(buff, nb); /* ensure it uses a dot */ + } + else { /* integers */ + lua_Integer n = lua_tointeger(L, arg); + const char *format = (n == LUA_MININTEGER) /* corner case? */ + ? "0x%" LUA_INTEGER_FRMLEN "x" /* use hexa */ + : LUA_INTEGER_FMT; /* else use default format */ + nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n); + } + luaL_addsize(b, nb); + break; + } + case LUA_TNIL: case LUA_TBOOLEAN: { + luaL_tolstring(L, arg, NULL); + luaL_addvalue(b); + break; + } + default: { + luaL_argerror(L, arg, "value has no literal form"); + } + } +} + + static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { const char *p = strfrmt; while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ @@ -975,41 +1035,47 @@ static int str_format (lua_State *L) { strfrmt = scanformat(L, strfrmt, form); switch (*strfrmt++) { case 'c': { - nb = sprintf(buff, form, (int)luaL_checkinteger(L, arg)); + nb = l_sprintf(buff, MAX_ITEM, form, (int)luaL_checkinteger(L, arg)); break; } case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': { lua_Integer n = luaL_checkinteger(L, arg); addlenmod(form, LUA_INTEGER_FRMLEN); - nb = sprintf(buff, form, n); + nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACINT)n); break; } case 'a': case 'A': addlenmod(form, LUA_NUMBER_FRMLEN); - nb = lua_number2strx(L, buff, form, luaL_checknumber(L, arg)); + nb = lua_number2strx(L, buff, MAX_ITEM, form, + luaL_checknumber(L, arg)); break; case 'e': case 'E': case 'f': case 'g': case 'G': { + lua_Number n = luaL_checknumber(L, arg); addlenmod(form, LUA_NUMBER_FRMLEN); - nb = sprintf(buff, form, luaL_checknumber(L, arg)); + nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACNUMBER)n); break; } case 'q': { - addquoted(L, &b, arg); + addliteral(L, &b, arg); break; } case 's': { size_t l; const char *s = luaL_tolstring(L, arg, &l); - if (!strchr(form, '.') && l >= 100) { - /* no precision and string is too long to be formatted; - keep original string */ - luaL_addvalue(&b); - } + if (form[2] == '\0') /* no modifiers? */ + luaL_addvalue(&b); /* keep entire string */ else { - nb = sprintf(buff, form, s); - lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ + luaL_argcheck(L, l == strlen(s), arg, "string contains zeros"); + if (!strchr(form, '.') && l >= 100) { + /* no precision and string is too long to be formatted */ + luaL_addvalue(&b); /* keep entire string */ + } + else { /* format the string into 'buff' */ + nb = l_sprintf(buff, MAX_ITEM, form, s); + lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ + } } break; } @@ -1018,6 +1084,7 @@ static int str_format (lua_State *L) { *(strfrmt - 1)); } } + lua_assert(nb < MAX_ITEM); luaL_addsize(&b, nb); } } @@ -1036,8 +1103,8 @@ static int str_format (lua_State *L) { /* value used for padding */ -#if !defined(LUA_PACKPADBYTE) -#define LUA_PACKPADBYTE 0x00 +#if !defined(LUAL_PACKPADBYTE) +#define LUAL_PACKPADBYTE 0x00 #endif /* maximum size for the binary representation of an integer */ @@ -1132,8 +1199,8 @@ static int getnum (const char **fmt, int df) { static int getnumlimit (Header *h, const char **fmt, int df) { int sz = getnum(fmt, df); if (sz > MAXINTSIZE || sz <= 0) - luaL_error(h->L, "integral size (%d) out of limits [1,%d]", - sz, MAXINTSIZE); + return luaL_error(h->L, "integral size (%d) out of limits [1,%d]", + sz, MAXINTSIZE); return sz; } @@ -1194,7 +1261,7 @@ static KOption getoption (Header *h, const char **fmt, int *size) { ** 'psize' is filled with option's size, 'notoalign' with its ** alignment requirements. ** Local variable 'size' gets the size to be aligned. (Kpadal option -** always gets its full alignment, other options are limited by +** always gets its full alignment, other options are limited by ** the maximum alignment ('maxalign'). Kchar option needs no alignment ** despite its size. */ @@ -1274,7 +1341,7 @@ static int str_pack (lua_State *L) { KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); totalsize += ntoalign + size; while (ntoalign-- > 0) - luaL_addchar(&b, LUA_PACKPADBYTE); /* fill alignment */ + luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */ arg++; switch (opt) { case Kint: { /* signed integers */ @@ -1309,8 +1376,11 @@ static int str_pack (lua_State *L) { case Kchar: { /* fixed-size string */ size_t len; const char *s = luaL_checklstring(L, arg, &len); - luaL_argcheck(L, len == (size_t)size, arg, "wrong length"); - luaL_addlstring(&b, s, size); + luaL_argcheck(L, len <= (size_t)size, arg, + "string longer than given size"); + luaL_addlstring(&b, s, len); /* add string */ + while (len++ < (size_t)size) /* pad extra space */ + luaL_addchar(&b, LUAL_PACKPADBYTE); break; } case Kstring: { /* strings with length count */ @@ -1333,7 +1403,7 @@ static int str_pack (lua_State *L) { totalsize += len + 1; break; } - case Kpadding: luaL_addchar(&b, LUA_PACKPADBYTE); /* FALLTHROUGH */ + case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE); /* FALLTHROUGH */ case Kpaddalign: case Knop: arg--; /* undo increment */ break; @@ -1360,7 +1430,7 @@ static int str_packsize (lua_State *L) { case Kstring: /* strings with length count */ case Kzstr: /* zero-terminated string */ luaL_argerror(L, 1, "variable-length format"); - break; + /* call never return, but to avoid warnings: *//* FALLTHROUGH */ default: break; } } diff --git a/source/extern/lua/ltable.c b/source/extern/lua/ltable.c index 04f2a34..ea4fe7f 100644 --- a/source/extern/lua/ltable.c +++ b/source/extern/lua/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 2.111 2015/06/09 14:21:13 roberto Exp $ +** $Id: ltable.c,v 2.118.1.4 2018/06/08 16:22:51 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -74,8 +74,6 @@ #define dummynode (&dummynode_) -#define isdummy(n) ((n) == dummynode) - static const Node dummynode_ = { {NILCONSTANT}, /* value */ {{NILCONSTANT, 0}} /* key */ @@ -85,7 +83,7 @@ static const Node dummynode_ = { /* ** Hash for floating-point numbers. ** The main computation should be just -** n = frepx(n, &i); return (n * INT_MAX) + i +** n = frexp(n, &i); return (n * INT_MAX) + i ** but there are some numerical subtleties. ** In a two-complement representation, INT_MAX does not has an exact ** representation as a float, but INT_MIN does; because the absolute @@ -101,7 +99,7 @@ static int l_hashfloat (lua_Number n) { lua_Integer ni; n = l_mathop(frexp)(n, &i) * -cast_num(INT_MIN); if (!lua_numbertointeger(n, &ni)) { /* is 'n' inf/-inf/NaN? */ - lua_assert(luai_numisnan(n) || l_mathop(fabs)(n) == HUGE_VAL); + lua_assert(luai_numisnan(n) || l_mathop(fabs)(n) == cast_num(HUGE_VAL)); return 0; } else { /* normal case */ @@ -124,14 +122,8 @@ static Node *mainposition (const Table *t, const TValue *key) { return hashmod(t, l_hashfloat(fltvalue(key))); case LUA_TSHRSTR: return hashstr(t, tsvalue(key)); - case LUA_TLNGSTR: { - TString *s = tsvalue(key); - if (s->extra == 0) { /* no hash? */ - s->hash = luaS_hash(getstr(s), s->u.lnglen, s->hash); - s->extra = 1; /* now it has its hash */ - } - return hashstr(t, tsvalue(key)); - } + case LUA_TLNGSTR: + return hashpow2(t, luaS_hashlongstr(tsvalue(key))); case LUA_TBOOLEAN: return hashboolean(t, bvalue(key)); case LUA_TLIGHTUSERDATA: @@ -139,6 +131,7 @@ static Node *mainposition (const Table *t, const TValue *key) { case LUA_TLCF: return hashpointer(t, fvalue(key)); default: + lua_assert(!ttisdeadkey(key)); return hashpointer(t, gcvalue(key)); } } @@ -230,7 +223,9 @@ static unsigned int computesizes (unsigned int nums[], unsigned int *pna) { unsigned int na = 0; /* number of elements to go to array part */ unsigned int optimal = 0; /* optimal size for array part */ /* loop while keys can fill more than half of total size */ - for (i = 0, twotoi = 1; *pna > twotoi / 2; i++, twotoi *= 2) { + for (i = 0, twotoi = 1; + twotoi > 0 && *pna > twotoi / 2; + i++, twotoi *= 2) { if (nums[i] > 0) { a += nums[i]; if (a > twotoi/2) { /* more than half elements present? */ @@ -313,14 +308,14 @@ static void setarrayvector (lua_State *L, Table *t, unsigned int size) { static void setnodevector (lua_State *L, Table *t, unsigned int size) { - int lsize; if (size == 0) { /* no elements to hash part? */ t->node = cast(Node *, dummynode); /* use common 'dummynode' */ - lsize = 0; + t->lsizenode = 0; + t->lastfree = NULL; /* signal that it is using dummy node */ } else { int i; - lsize = luaO_ceillog2(size); + int lsize = luaO_ceillog2(size); if (lsize > MAXHBITS) luaG_runerror(L, "table overflow"); size = twoto(lsize); @@ -331,9 +326,21 @@ static void setnodevector (lua_State *L, Table *t, unsigned int size) { setnilvalue(wgkey(n)); setnilvalue(gval(n)); } + t->lsizenode = cast_byte(lsize); + t->lastfree = gnode(t, size); /* all positions are free */ } - t->lsizenode = cast_byte(lsize); - t->lastfree = gnode(t, size); /* all positions are free */ +} + + +typedef struct { + Table *t; + unsigned int nhsize; +} AuxsetnodeT; + + +static void auxsetnode (lua_State *L, void *ud) { + AuxsetnodeT *asn = cast(AuxsetnodeT *, ud); + setnodevector(L, asn->t, asn->nhsize); } @@ -341,13 +348,18 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize, unsigned int nhsize) { unsigned int i; int j; + AuxsetnodeT asn; unsigned int oldasize = t->sizearray; - int oldhsize = t->lsizenode; + int oldhsize = allocsizenode(t); Node *nold = t->node; /* save old hash ... */ if (nasize > oldasize) /* array part must grow? */ setarrayvector(L, t, nasize); /* create new hash part with appropriate size */ - setnodevector(L, t, nhsize); + asn.t = t; asn.nhsize = nhsize; + if (luaD_rawrunprotected(L, auxsetnode, &asn) != LUA_OK) { /* mem. error? */ + setarrayvector(L, t, oldasize); /* array back to its original size */ + luaD_throw(L, LUA_ERRMEM); /* rethrow memory error */ + } if (nasize < oldasize) { /* array part must shrink? */ t->sizearray = nasize; /* re-insert elements from vanishing slice */ @@ -359,7 +371,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize, luaM_reallocvector(L, t->array, oldasize, nasize, TValue); } /* re-insert elements from hash part */ - for (j = twoto(oldhsize) - 1; j >= 0; j--) { + for (j = oldhsize - 1; j >= 0; j--) { Node *old = nold + j; if (!ttisnil(gval(old))) { /* doesn't need barrier/invalidate cache, as entry was @@ -367,13 +379,13 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize, setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old)); } } - if (!isdummy(nold)) - luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old hash */ + if (oldhsize > 0) /* not the dummy node? */ + luaM_freearray(L, nold, cast(size_t, oldhsize)); /* free old hash */ } void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) { - int nsize = isdummy(t->node) ? 0 : sizenode(t); + int nsize = allocsizenode(t); luaH_resize(L, t, nasize, nsize); } @@ -419,7 +431,7 @@ Table *luaH_new (lua_State *L) { void luaH_free (lua_State *L, Table *t) { - if (!isdummy(t->node)) + if (!isdummy(t)) luaM_freearray(L, t->node, cast(size_t, sizenode(t))); luaM_freearray(L, t->array, t->sizearray); luaM_free(L, t); @@ -427,10 +439,12 @@ void luaH_free (lua_State *L, Table *t) { static Node *getfreepos (Table *t) { - while (t->lastfree > t->node) { - t->lastfree--; - if (ttisnil(gkey(t->lastfree))) - return t->lastfree; + if (!isdummy(t)) { + while (t->lastfree > t->node) { + t->lastfree--; + if (ttisnil(gkey(t->lastfree))) + return t->lastfree; + } } return NULL; /* could not find a free place */ } @@ -450,7 +464,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { if (ttisnil(key)) luaG_runerror(L, "table index is nil"); else if (ttisfloat(key)) { lua_Integer k; - if (luaV_tointeger(key, &k, 0)) { /* index is int? */ + if (luaV_tointeger(key, &k, 0)) { /* does index fit in an integer? */ setivalue(&aux, k); key = &aux; /* insert it as an integer */ } @@ -458,15 +472,15 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { luaG_runerror(L, "table index is NaN"); } mp = mainposition(t, key); - if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ + if (!ttisnil(gval(mp)) || isdummy(t)) { /* main position is taken? */ Node *othern; Node *f = getfreepos(t); /* get a free place */ if (f == NULL) { /* cannot find a free place? */ rehash(L, t, key); /* grow table */ - /* whatever called 'newkey' takes care of TM cache and GC barrier */ + /* whatever called 'newkey' takes care of TM cache */ return luaH_set(L, t, key); /* insert key into grown table */ } - lua_assert(!isdummy(f)); + lua_assert(!isdummy(t)); othern = mainposition(t, gkey(mp)); if (othern != mp) { /* is colliding node out of its main position? */ /* yes; move colliding node into free position */ @@ -501,7 +515,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { */ const TValue *luaH_getint (Table *t, lua_Integer key) { /* (1 <= key && key <= t->sizearray) */ - if (l_castS2U(key - 1) < t->sizearray) + if (l_castS2U(key) - 1 < t->sizearray) return &t->array[key - 1]; else { Node *n = hashint(t, key); @@ -513,7 +527,7 @@ const TValue *luaH_getint (Table *t, lua_Integer key) { if (nx == 0) break; n += nx; } - }; + } return luaO_nilobject; } } @@ -522,7 +536,7 @@ const TValue *luaH_getint (Table *t, lua_Integer key) { /* ** search function for short strings */ -const TValue *luaH_getstr (Table *t, TString *key) { +const TValue *luaH_getshortstr (Table *t, TString *key) { Node *n = hashstr(t, key); lua_assert(key->tt == LUA_TSHRSTR); for (;;) { /* check whether 'key' is somewhere in the chain */ @@ -531,11 +545,41 @@ const TValue *luaH_getstr (Table *t, TString *key) { return gval(n); /* that's it */ else { int nx = gnext(n); - if (nx == 0) break; + if (nx == 0) + return luaO_nilobject; /* not found */ n += nx; } - }; - return luaO_nilobject; + } +} + + +/* +** "Generic" get version. (Not that generic: not valid for integers, +** which may be in array part, nor for floats with integral values.) +*/ +static const TValue *getgeneric (Table *t, const TValue *key) { + Node *n = mainposition(t, key); + for (;;) { /* check whether 'key' is somewhere in the chain */ + if (luaV_rawequalobj(gkey(n), key)) + return gval(n); /* that's it */ + else { + int nx = gnext(n); + if (nx == 0) + return luaO_nilobject; /* not found */ + n += nx; + } + } +} + + +const TValue *luaH_getstr (Table *t, TString *key) { + if (key->tt == LUA_TSHRSTR) + return luaH_getshortstr(t, key); + else { /* for long strings, use generic case */ + TValue ko; + setsvalue(cast(lua_State *, NULL), &ko, key); + return getgeneric(t, &ko); + } } @@ -544,7 +588,7 @@ const TValue *luaH_getstr (Table *t, TString *key) { */ const TValue *luaH_get (Table *t, const TValue *key) { switch (ttype(key)) { - case LUA_TSHRSTR: return luaH_getstr(t, tsvalue(key)); + case LUA_TSHRSTR: return luaH_getshortstr(t, tsvalue(key)); case LUA_TNUMINT: return luaH_getint(t, ivalue(key)); case LUA_TNIL: return luaO_nilobject; case LUA_TNUMFLT: { @@ -553,19 +597,8 @@ const TValue *luaH_get (Table *t, const TValue *key) { return luaH_getint(t, k); /* use specialized version */ /* else... */ } /* FALLTHROUGH */ - default: { - Node *n = mainposition(t, key); - for (;;) { /* check whether 'key' is somewhere in the chain */ - if (luaV_rawequalobj(gkey(n), key)) - return gval(n); /* that's it */ - else { - int nx = gnext(n); - if (nx == 0) break; - n += nx; - } - }; - return luaO_nilobject; - } + default: + return getgeneric(t, key); } } @@ -596,13 +629,13 @@ void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { } -static int unbound_search (Table *t, unsigned int j) { - unsigned int i = j; /* i is zero or a present index */ +static lua_Unsigned unbound_search (Table *t, lua_Unsigned j) { + lua_Unsigned i = j; /* i is zero or a present index */ j++; /* find 'i' and 'j' such that i is present and j is not */ while (!ttisnil(luaH_getint(t, j))) { i = j; - if (j > cast(unsigned int, MAX_INT)/2) { /* overflow? */ + if (j > l_castS2U(LUA_MAXINTEGER) / 2) { /* overflow? */ /* table was built with bad purposes: resort to linear search */ i = 1; while (!ttisnil(luaH_getint(t, i))) i++; @@ -612,7 +645,7 @@ static int unbound_search (Table *t, unsigned int j) { } /* now do a binary search between them */ while (j - i > 1) { - unsigned int m = (i+j)/2; + lua_Unsigned m = (i+j)/2; if (ttisnil(luaH_getint(t, m))) j = m; else i = m; } @@ -624,7 +657,7 @@ static int unbound_search (Table *t, unsigned int j) { ** Try to find a boundary in table 't'. A 'boundary' is an integer index ** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). */ -int luaH_getn (Table *t) { +lua_Unsigned luaH_getn (Table *t) { unsigned int j = t->sizearray; if (j > 0 && ttisnil(&t->array[j - 1])) { /* there is a boundary in the array part: (binary) search for it */ @@ -637,7 +670,7 @@ int luaH_getn (Table *t) { return i; } /* else must find a boundary in hash part */ - else if (isdummy(t->node)) /* hash part is empty? */ + else if (isdummy(t)) /* hash part is empty? */ return j; /* that is easy... */ else return unbound_search(t, j); } @@ -650,6 +683,6 @@ Node *luaH_mainposition (const Table *t, const TValue *key) { return mainposition(t, key); } -int luaH_isdummy (Node *n) { return isdummy(n); } +int luaH_isdummy (const Table *t) { return isdummy(t); } #endif diff --git a/source/extern/lua/ltable.h b/source/extern/lua/ltable.h index 53d2551..92db0ac 100644 --- a/source/extern/lua/ltable.h +++ b/source/extern/lua/ltable.h @@ -1,5 +1,5 @@ /* -** $Id: ltable.h,v 2.20 2014/09/04 18:15:29 roberto Exp $ +** $Id: ltable.h,v 2.23.1.2 2018/05/24 19:39:05 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -15,14 +15,26 @@ #define gnext(n) ((n)->i_key.nk.next) -/* 'const' to avoid wrong writings that can mess up field 'next' */ +/* 'const' to avoid wrong writings that can mess up field 'next' */ #define gkey(n) cast(const TValue*, (&(n)->i_key.tvk)) +/* +** writable version of 'gkey'; allows updates to individual fields, +** but not to the whole (which has incompatible type) +*/ #define wgkey(n) (&(n)->i_key.nk) #define invalidateTMcache(t) ((t)->flags = 0) +/* true when 't' is using 'dummynode' as its hash part */ +#define isdummy(t) ((t)->lastfree == NULL) + + +/* allocated size for hash nodes */ +#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) + + /* returns the key, given the value of a table entry */ #define keyfromval(v) \ (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val)))) @@ -31,6 +43,7 @@ LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value); +LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); @@ -41,12 +54,12 @@ LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); LUAI_FUNC void luaH_free (lua_State *L, Table *t); LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); -LUAI_FUNC int luaH_getn (Table *t); +LUAI_FUNC lua_Unsigned luaH_getn (Table *t); #if defined(LUA_DEBUG) LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); -LUAI_FUNC int luaH_isdummy (Node *n); +LUAI_FUNC int luaH_isdummy (const Table *t); #endif diff --git a/source/extern/lua/ltablib.c b/source/extern/lua/ltablib.c index a05c885..c534957 100644 --- a/source/extern/lua/ltablib.c +++ b/source/extern/lua/ltablib.c @@ -1,5 +1,5 @@ /* -** $Id: ltablib.c,v 1.80 2015/01/13 16:27:29 roberto Exp $ +** $Id: ltablib.c,v 1.93.1.1 2017/04/19 17:20:42 roberto Exp $ ** Library for Table Manipulation ** See Copyright Notice in lua.h */ @@ -12,6 +12,7 @@ #include #include +#include #include "lua.h" @@ -19,40 +20,42 @@ #include "lualib.h" - /* -** Structure with table-access functions +** Operations that an object must define to mimic a table +** (some functions only need some of them) */ -typedef struct { - int (*geti) (lua_State *L, int idx, lua_Integer n); - void (*seti) (lua_State *L, int idx, lua_Integer n); -} TabA; +#define TAB_R 1 /* read */ +#define TAB_W 2 /* write */ +#define TAB_L 4 /* length */ +#define TAB_RW (TAB_R | TAB_W) /* read/write */ -/* -** Check that 'arg' has a table and set access functions in 'ta' to raw -** or non-raw according to the presence of corresponding metamethods. -*/ -static void checktab (lua_State *L, int arg, TabA *ta) { - ta->geti = NULL; ta->seti = NULL; - if (lua_getmetatable(L, arg)) { - lua_pushliteral(L, "__index"); /* 'index' metamethod */ - if (lua_rawget(L, -2) != LUA_TNIL) - ta->geti = lua_geti; - lua_pushliteral(L, "__newindex"); /* 'newindex' metamethod */ - if (lua_rawget(L, -3) != LUA_TNIL) - ta->seti = lua_seti; - lua_pop(L, 3); /* pop metatable plus both metamethods */ - } - if (ta->geti == NULL || ta->seti == NULL) { - luaL_checktype(L, arg, LUA_TTABLE); /* must be table for raw methods */ - if (ta->geti == NULL) ta->geti = lua_rawgeti; - if (ta->seti == NULL) ta->seti = lua_rawseti; - } +#define aux_getn(L,n,w) (checktab(L, n, (w) | TAB_L), luaL_len(L, n)) + + +static int checkfield (lua_State *L, const char *key, int n) { + lua_pushstring(L, key); + return (lua_rawget(L, -n) != LUA_TNIL); } -#define aux_getn(L,n,ta) (checktab(L, n, ta), luaL_len(L, n)) +/* +** Check that 'arg' either is a table or can behave like one (that is, +** has a metatable with the required metamethods) +*/ +static void checktab (lua_State *L, int arg, int what) { + if (lua_type(L, arg) != LUA_TTABLE) { /* is it not a table? */ + int n = 1; /* number of elements to pop */ + if (lua_getmetatable(L, arg) && /* must have metatable */ + (!(what & TAB_R) || checkfield(L, "__index", ++n)) && + (!(what & TAB_W) || checkfield(L, "__newindex", ++n)) && + (!(what & TAB_L) || checkfield(L, "__len", ++n))) { + lua_pop(L, n); /* pop metatable and tested metamethods */ + } + else + luaL_checktype(L, arg, LUA_TTABLE); /* force an error */ + } +} #if defined(LUA_COMPAT_MAXN) @@ -74,8 +77,7 @@ static int maxn (lua_State *L) { static int tinsert (lua_State *L) { - TabA ta; - lua_Integer e = aux_getn(L, 1, &ta) + 1; /* first empty element */ + lua_Integer e = aux_getn(L, 1, TAB_RW) + 1; /* first empty element */ lua_Integer pos; /* where to insert new element */ switch (lua_gettop(L)) { case 2: { /* called with only 2 arguments */ @@ -87,8 +89,8 @@ static int tinsert (lua_State *L) { pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */ luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds"); for (i = e; i > pos; i--) { /* move up elements */ - (*ta.geti)(L, 1, i - 1); - (*ta.seti)(L, 1, i); /* t[i] = t[i - 1] */ + lua_geti(L, 1, i - 1); + lua_seti(L, 1, i); /* t[i] = t[i - 1] */ } break; } @@ -96,67 +98,67 @@ static int tinsert (lua_State *L) { return luaL_error(L, "wrong number of arguments to 'insert'"); } } - (*ta.seti)(L, 1, pos); /* t[pos] = v */ + lua_seti(L, 1, pos); /* t[pos] = v */ return 0; } static int tremove (lua_State *L) { - TabA ta; - lua_Integer size = aux_getn(L, 1, &ta); + lua_Integer size = aux_getn(L, 1, TAB_RW); lua_Integer pos = luaL_optinteger(L, 2, size); if (pos != size) /* validate 'pos' if given */ luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds"); - (*ta.geti)(L, 1, pos); /* result = t[pos] */ + lua_geti(L, 1, pos); /* result = t[pos] */ for ( ; pos < size; pos++) { - (*ta.geti)(L, 1, pos + 1); - (*ta.seti)(L, 1, pos); /* t[pos] = t[pos + 1] */ + lua_geti(L, 1, pos + 1); + lua_seti(L, 1, pos); /* t[pos] = t[pos + 1] */ } lua_pushnil(L); - (*ta.seti)(L, 1, pos); /* t[pos] = nil */ + lua_seti(L, 1, pos); /* t[pos] = nil */ return 1; } +/* +** Copy elements (1[f], ..., 1[e]) into (tt[t], tt[t+1], ...). Whenever +** possible, copy in increasing order, which is better for rehashing. +** "possible" means destination after original range, or smaller +** than origin, or copying to another table. +*/ static int tmove (lua_State *L) { - TabA ta; lua_Integer f = luaL_checkinteger(L, 2); lua_Integer e = luaL_checkinteger(L, 3); lua_Integer t = luaL_checkinteger(L, 4); int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ + checktab(L, 1, TAB_R); + checktab(L, tt, TAB_W); if (e >= f) { /* otherwise, nothing to move */ lua_Integer n, i; - ta.geti = (luaL_getmetafield(L, 1, "__index") == LUA_TNIL) - ? (luaL_checktype(L, 1, LUA_TTABLE), lua_rawgeti) - : lua_geti; - ta.seti = (luaL_getmetafield(L, tt, "__newindex") == LUA_TNIL) - ? (luaL_checktype(L, tt, LUA_TTABLE), lua_rawseti) - : lua_seti; luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3, "too many elements to move"); n = e - f + 1; /* number of elements to move */ luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4, "destination wrap around"); - if (t > f) { - for (i = n - 1; i >= 0; i--) { - (*ta.geti)(L, 1, f + i); - (*ta.seti)(L, tt, t + i); + if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) { + for (i = 0; i < n; i++) { + lua_geti(L, 1, f + i); + lua_seti(L, tt, t + i); } } else { - for (i = 0; i < n; i++) { - (*ta.geti)(L, 1, f + i); - (*ta.seti)(L, tt, t + i); + for (i = n - 1; i >= 0; i--) { + lua_geti(L, 1, f + i); + lua_seti(L, tt, t + i); } } } - lua_pushvalue(L, tt); /* return "to table" */ + lua_pushvalue(L, tt); /* return destination table */ return 1; } -static void addfield (lua_State *L, luaL_Buffer *b, TabA *ta, lua_Integer i) { - (*ta->geti)(L, 1, i); +static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) { + lua_geti(L, 1, i); if (!lua_isstring(L, -1)) luaL_error(L, "invalid value (%s) at index %d in table for 'concat'", luaL_typename(L, -1), i); @@ -165,21 +167,19 @@ static void addfield (lua_State *L, luaL_Buffer *b, TabA *ta, lua_Integer i) { static int tconcat (lua_State *L) { - TabA ta; luaL_Buffer b; + lua_Integer last = aux_getn(L, 1, TAB_R); size_t lsep; - lua_Integer i, last; const char *sep = luaL_optlstring(L, 2, "", &lsep); - checktab(L, 1, &ta); - i = luaL_optinteger(L, 3, 1); - last = luaL_opt(L, luaL_checkinteger, 4, luaL_len(L, 1)); + lua_Integer i = luaL_optinteger(L, 3, 1); + last = luaL_optinteger(L, 4, last); luaL_buffinit(L, &b); for (; i < last; i++) { - addfield(L, &b, &ta, i); + addfield(L, &b, i); luaL_addlstring(&b, sep, lsep); } if (i == last) /* add last value (if interval was not empty) */ - addfield(L, &b, &ta, i); + addfield(L, &b, i); luaL_pushresult(&b); return 1; } @@ -197,7 +197,7 @@ static int pack (lua_State *L) { lua_createtable(L, n, 1); /* create result table */ lua_insert(L, 1); /* put it at index 1 */ for (i = n; i >= 1; i--) /* assign elements */ - lua_rawseti(L, 1, i); + lua_seti(L, 1, i); lua_pushinteger(L, n); lua_setfield(L, 1, "n"); /* t.n = number of elements */ return 1; /* return table */ @@ -205,20 +205,17 @@ static int pack (lua_State *L) { static int unpack (lua_State *L) { - TabA ta; - lua_Integer i, e; lua_Unsigned n; - checktab(L, 1, &ta); - i = luaL_optinteger(L, 2, 1); - e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); + lua_Integer i = luaL_optinteger(L, 2, 1); + lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); if (i > e) return 0; /* empty range */ n = (lua_Unsigned)e - i; /* number of elements minus 1 (avoid overflows) */ if (n >= (unsigned int)INT_MAX || !lua_checkstack(L, (int)(++n))) return luaL_error(L, "too many results to unpack"); - do { /* must have at least one element */ - (*ta.geti)(L, 1, i); /* push arg[i..e] */ - } while (i++ < e); - + for (; i < e; i++) { /* push arg[i..e - 1] (to avoid overflows) */ + lua_geti(L, 1, i); + } + lua_geti(L, 1, e); /* push last element */ return (int)n; } @@ -235,97 +232,191 @@ static int unpack (lua_State *L) { */ -static void set2 (lua_State *L, TabA *ta, int i, int j) { - (*ta->seti)(L, 1, i); - (*ta->seti)(L, 1, j); +/* type for array indices */ +typedef unsigned int IdxT; + + +/* +** Produce a "random" 'unsigned int' to randomize pivot choice. This +** macro is used only when 'sort' detects a big imbalance in the result +** of a partition. (If you don't want/need this "randomness", ~0 is a +** good choice.) +*/ +#if !defined(l_randomizePivot) /* { */ + +#include + +/* size of 'e' measured in number of 'unsigned int's */ +#define sof(e) (sizeof(e) / sizeof(unsigned int)) + +/* +** Use 'time' and 'clock' as sources of "randomness". Because we don't +** know the types 'clock_t' and 'time_t', we cannot cast them to +** anything without risking overflows. A safe way to use their values +** is to copy them to an array of a known type and use the array values. +*/ +static unsigned int l_randomizePivot (void) { + clock_t c = clock(); + time_t t = time(NULL); + unsigned int buff[sof(c) + sof(t)]; + unsigned int i, rnd = 0; + memcpy(buff, &c, sof(c) * sizeof(unsigned int)); + memcpy(buff + sof(c), &t, sof(t) * sizeof(unsigned int)); + for (i = 0; i < sof(buff); i++) + rnd += buff[i]; + return rnd; } +#endif /* } */ + + +/* arrays larger than 'RANLIMIT' may use randomized pivots */ +#define RANLIMIT 100u + + +static void set2 (lua_State *L, IdxT i, IdxT j) { + lua_seti(L, 1, i); + lua_seti(L, 1, j); +} + + +/* +** Return true iff value at stack index 'a' is less than the value at +** index 'b' (according to the order of the sort). +*/ static int sort_comp (lua_State *L, int a, int b) { - if (!lua_isnil(L, 2)) { /* function? */ + if (lua_isnil(L, 2)) /* no function? */ + return lua_compare(L, a, b, LUA_OPLT); /* a < b */ + else { /* function */ int res; - lua_pushvalue(L, 2); + lua_pushvalue(L, 2); /* push function */ lua_pushvalue(L, a-1); /* -1 to compensate function */ lua_pushvalue(L, b-2); /* -2 to compensate function and 'a' */ - lua_call(L, 2, 1); - res = lua_toboolean(L, -1); - lua_pop(L, 1); + lua_call(L, 2, 1); /* call function */ + res = lua_toboolean(L, -1); /* get result */ + lua_pop(L, 1); /* pop result */ return res; } - else /* a < b? */ - return lua_compare(L, a, b, LUA_OPLT); } -static void auxsort (lua_State *L, TabA *ta, int l, int u) { - while (l < u) { /* for tail recursion */ - int i, j; - /* sort elements a[l], a[(l+u)/2] and a[u] */ - (*ta->geti)(L, 1, l); - (*ta->geti)(L, 1, u); - if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */ - set2(L, ta, l, u); /* swap a[l] - a[u] */ + +/* +** Does the partition: Pivot P is at the top of the stack. +** precondition: a[lo] <= P == a[up-1] <= a[up], +** so it only needs to do the partition from lo + 1 to up - 2. +** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up] +** returns 'i'. +*/ +static IdxT partition (lua_State *L, IdxT lo, IdxT up) { + IdxT i = lo; /* will be incremented before first use */ + IdxT j = up - 1; /* will be decremented before first use */ + /* loop invariant: a[lo .. i] <= P <= a[j .. up] */ + for (;;) { + /* next loop: repeat ++i while a[i] < P */ + while (lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) { + if (i == up - 1) /* a[i] < P but a[up - 1] == P ?? */ + luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[i] */ + } + /* after the loop, a[i] >= P and a[lo .. i - 1] < P */ + /* next loop: repeat --j while P < a[j] */ + while (lua_geti(L, 1, --j), sort_comp(L, -3, -1)) { + if (j < i) /* j < i but a[j] > P ?? */ + luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[j] */ + } + /* after the loop, a[j] <= P and a[j + 1 .. up] >= P */ + if (j < i) { /* no elements out of place? */ + /* a[lo .. i - 1] <= P <= a[j + 1 .. i .. up] */ + lua_pop(L, 1); /* pop a[j] */ + /* swap pivot (a[up - 1]) with a[i] to satisfy pos-condition */ + set2(L, up - 1, i); + return i; + } + /* otherwise, swap a[i] - a[j] to restore invariant and repeat */ + set2(L, i, j); + } +} + + +/* +** Choose an element in the middle (2nd-3th quarters) of [lo,up] +** "randomized" by 'rnd' +*/ +static IdxT choosePivot (IdxT lo, IdxT up, unsigned int rnd) { + IdxT r4 = (up - lo) / 4; /* range/4 */ + IdxT p = rnd % (r4 * 2) + (lo + r4); + lua_assert(lo + r4 <= p && p <= up - r4); + return p; +} + + +/* +** QuickSort algorithm (recursive function) +*/ +static void auxsort (lua_State *L, IdxT lo, IdxT up, + unsigned int rnd) { + while (lo < up) { /* loop for tail recursion */ + IdxT p; /* Pivot index */ + IdxT n; /* to be used later */ + /* sort elements 'lo', 'p', and 'up' */ + lua_geti(L, 1, lo); + lua_geti(L, 1, up); + if (sort_comp(L, -1, -2)) /* a[up] < a[lo]? */ + set2(L, lo, up); /* swap a[lo] - a[up] */ else - lua_pop(L, 2); - if (u-l == 1) break; /* only 2 elements */ - i = (l+u)/2; - (*ta->geti)(L, 1, i); - (*ta->geti)(L, 1, l); - if (sort_comp(L, -2, -1)) /* a[i]geti)(L, 1, u); - if (sort_comp(L, -1, -2)) /* a[u]geti)(L, 1, i); /* Pivot */ - lua_pushvalue(L, -1); - (*ta->geti)(L, 1, u-1); - set2(L, ta, i, u-1); - /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */ - i = l; j = u-1; - for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ - /* repeat ++i until a[i] >= P */ - while ((*ta->geti)(L, 1, ++i), sort_comp(L, -1, -2)) { - if (i>=u) luaL_error(L, "invalid order function for sorting"); - lua_pop(L, 1); /* remove a[i] */ - } - /* repeat --j until a[j] <= P */ - while ((*ta->geti)(L, 1, --j), sort_comp(L, -3, -1)) { - if (j<=l) luaL_error(L, "invalid order function for sorting"); - lua_pop(L, 1); /* remove a[j] */ - } - if (jgeti)(L, 1, u-1); - (*ta->geti)(L, 1, i); - set2(L, ta, u-1, i); /* swap pivot (a[u-1]) with a[i] */ - /* a[l..i-1] <= a[i] == P <= a[i+1..u] */ - /* adjust so that smaller half is in [j..i] and larger one in [l..u] */ - if (i-l < u-i) { - j=l; i=i-1; l=i+2; + if (up - lo == 2) /* only 3 elements? */ + return; /* already sorted */ + lua_geti(L, 1, p); /* get middle element (Pivot) */ + lua_pushvalue(L, -1); /* push Pivot */ + lua_geti(L, 1, up - 1); /* push a[up - 1] */ + set2(L, p, up - 1); /* swap Pivot (a[p]) with a[up - 1] */ + p = partition(L, lo, up); + /* a[lo .. p - 1] <= a[p] == P <= a[p + 1 .. up] */ + if (p - lo < up - p) { /* lower interval is smaller? */ + auxsort(L, lo, p - 1, rnd); /* call recursively for lower interval */ + n = p - lo; /* size of smaller interval */ + lo = p + 1; /* tail call for [p + 1 .. up] (upper interval) */ } else { - j=i+1; i=u; u=j-2; + auxsort(L, p + 1, up, rnd); /* call recursively for upper interval */ + n = up - p; /* size of smaller interval */ + up = p - 1; /* tail call for [lo .. p - 1] (lower interval) */ } - auxsort(L, ta, j, i); /* call recursively the smaller one */ - } /* repeat the routine for the larger one */ + if ((up - lo) / 128 > n) /* partition too imbalanced? */ + rnd = l_randomizePivot(); /* try a new randomization */ + } /* tail call auxsort(L, lo, up, rnd) */ } + static int sort (lua_State *L) { - TabA ta; - int n = (int)aux_getn(L, 1, &ta); - luaL_checkstack(L, 50, ""); /* assume array is smaller than 2^50 */ - if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ - luaL_checktype(L, 2, LUA_TFUNCTION); - lua_settop(L, 2); /* make sure there are two arguments */ - auxsort(L, &ta, 1, n); + lua_Integer n = aux_getn(L, 1, TAB_RW); + if (n > 1) { /* non-trivial interval? */ + luaL_argcheck(L, n < INT_MAX, 1, "array too big"); + if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ + luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */ + lua_settop(L, 2); /* make sure there are two arguments */ + auxsort(L, 1, (IdxT)n, 0); + } return 0; } diff --git a/source/extern/lua/ltm.c b/source/extern/lua/ltm.c index c38e5c3..0e7c713 100644 --- a/source/extern/lua/ltm.c +++ b/source/extern/lua/ltm.c @@ -1,5 +1,5 @@ /* -** $Id: ltm.c,v 2.34 2015/03/30 15:42:27 roberto Exp $ +** $Id: ltm.c,v 2.38.1.1 2017/04/19 17:39:34 roberto Exp $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -15,7 +15,7 @@ #include "lua.h" #include "ldebug.h" -#include "ldo.h" +#include "ldo.h" #include "lobject.h" #include "lstate.h" #include "lstring.h" @@ -57,7 +57,7 @@ void luaT_init (lua_State *L) { ** tag methods */ const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { - const TValue *tm = luaH_getstr(events, ename); + const TValue *tm = luaH_getshortstr(events, ename); lua_assert(event <= TM_EQ); if (ttisnil(tm)) { /* no tag method? */ events->flags |= cast_byte(1u<mt[ttnov(o)]; } - return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); + return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : luaO_nilobject); +} + + +/* +** Return the name of the type of an object. For tables and userdata +** with metatable, use their '__name' metafield, if present. +*/ +const char *luaT_objtypename (lua_State *L, const TValue *o) { + Table *mt; + if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) || + (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) { + const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name")); + if (ttisstring(name)) /* is '__name' a string? */ + return getstr(tsvalue(name)); /* use it as type name */ + } + return ttypename(ttnov(o)); /* else use standard type name */ } void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, const TValue *p2, TValue *p3, int hasres) { ptrdiff_t result = savestack(L, p3); - setobj2s(L, L->top++, f); /* push function (assume EXTRA_STACK) */ - setobj2s(L, L->top++, p1); /* 1st argument */ - setobj2s(L, L->top++, p2); /* 2nd argument */ + StkId func = L->top; + setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ + setobj2s(L, func + 1, p1); /* 1st argument */ + setobj2s(L, func + 2, p2); /* 2nd argument */ + L->top += 3; if (!hasres) /* no result? 'p3' is third argument */ setobj2s(L, L->top++, p3); /* 3rd argument */ /* metamethod may yield only when called from Lua code */ - luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci)); + if (isLua(L->ci)) + luaD_call(L, func, hasres); + else + luaD_callnoyield(L, func, hasres); if (hasres) { /* if has result, move it to its place */ p3 = restorestack(L, result); setobjs2s(L, p3, --L->top); diff --git a/source/extern/lua/ltm.h b/source/extern/lua/ltm.h index 180179c..8170688 100644 --- a/source/extern/lua/ltm.h +++ b/source/extern/lua/ltm.h @@ -1,5 +1,5 @@ /* -** $Id: ltm.h,v 2.21 2014/10/25 11:50:46 roberto Exp $ +** $Id: ltm.h,v 2.22.1.1 2017/04/19 17:20:42 roberto Exp $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -51,11 +51,12 @@ typedef enum { #define fasttm(l,et,e) gfasttm(G(l), et, e) #define ttypename(x) luaT_typenames_[(x) + 1] -#define objtypename(x) ttypename(ttnov(x)) LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS]; +LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o); + LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event); diff --git a/source/extern/lua/lundump.c b/source/extern/lua/lundump.c index 510f325..edf9eb8 100644 --- a/source/extern/lua/lundump.c +++ b/source/extern/lua/lundump.c @@ -1,5 +1,5 @@ /* -** $Id: lundump.c,v 2.41 2014/11/02 19:19:04 roberto Exp $ +** $Id: lundump.c,v 2.44.1.1 2017/04/19 17:20:42 roberto Exp $ ** load precompiled Lua chunks ** See Copyright Notice in lua.h */ @@ -32,7 +32,6 @@ typedef struct { lua_State *L; ZIO *Z; - Mbuffer *b; const char *name; } LoadState; @@ -86,17 +85,28 @@ static lua_Integer LoadInteger (LoadState *S) { } -static TString *LoadString (LoadState *S) { +static TString *LoadString (LoadState *S, Proto *p) { + lua_State *L = S->L; size_t size = LoadByte(S); + TString *ts; if (size == 0xFF) LoadVar(S, size); if (size == 0) return NULL; - else { - char *s = luaZ_openspace(S->L, S->b, --size); - LoadVector(S, s, size); - return luaS_newlstr(S->L, s, size); + else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ + char buff[LUAI_MAXSHORTLEN]; + LoadVector(S, buff, size); + ts = luaS_newlstr(L, buff, size); } + else { /* long string */ + ts = luaS_createlngstrobj(L, size); + setsvalue2s(L, L->top, ts); /* anchor it ('loadVector' can GC) */ + luaD_inctop(L); + LoadVector(S, getstr(ts), size); /* load directly in final place */ + L->top--; /* pop string */ + } + luaC_objbarrier(L, p, ts); + return ts; } @@ -136,7 +146,7 @@ static void LoadConstants (LoadState *S, Proto *f) { break; case LUA_TSHRSTR: case LUA_TLNGSTR: - setsvalue2n(S->L, o, LoadString(S)); + setsvalue2n(S->L, o, LoadString(S, f)); break; default: lua_assert(0); @@ -154,6 +164,7 @@ static void LoadProtos (LoadState *S, Proto *f) { f->p[i] = NULL; for (i = 0; i < n; i++) { f->p[i] = luaF_newproto(S->L); + luaC_objbarrier(S->L, f, f->p[i]); LoadFunction(S, f->p[i], f->source); } } @@ -185,18 +196,18 @@ static void LoadDebug (LoadState *S, Proto *f) { for (i = 0; i < n; i++) f->locvars[i].varname = NULL; for (i = 0; i < n; i++) { - f->locvars[i].varname = LoadString(S); + f->locvars[i].varname = LoadString(S, f); f->locvars[i].startpc = LoadInt(S); f->locvars[i].endpc = LoadInt(S); } n = LoadInt(S); for (i = 0; i < n; i++) - f->upvalues[i].name = LoadString(S); + f->upvalues[i].name = LoadString(S, f); } static void LoadFunction (LoadState *S, Proto *f, TString *psource) { - f->source = LoadString(S); + f->source = LoadString(S, f); if (f->source == NULL) /* no source in dump? */ f->source = psource; /* reuse parent's source */ f->linedefined = LoadInt(S); @@ -251,8 +262,7 @@ static void checkHeader (LoadState *S) { /* ** load precompiled chunk */ -LClosure *luaU_undump(lua_State *L, ZIO *Z, Mbuffer *buff, - const char *name) { +LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { LoadState S; LClosure *cl; if (*name == '@' || *name == '=') @@ -263,12 +273,12 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, Mbuffer *buff, S.name = name; S.L = L; S.Z = Z; - S.b = buff; checkHeader(&S); cl = luaF_newLclosure(L, LoadByte(&S)); setclLvalue(L, L->top, cl); - incr_top(L); + luaD_inctop(L); cl->p = luaF_newproto(L); + luaC_objbarrier(L, cl, cl->p); LoadFunction(&S, cl->p, NULL); lua_assert(cl->nupvalues == cl->p->sizeupvalues); luai_verifycode(L, buff, cl->p); diff --git a/source/extern/lua/lundump.h b/source/extern/lua/lundump.h index ef43d51..ce492d6 100644 --- a/source/extern/lua/lundump.h +++ b/source/extern/lua/lundump.h @@ -1,5 +1,5 @@ /* -** $Id: lundump.h,v 1.44 2014/06/19 18:27:20 roberto Exp $ +** $Id: lundump.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $ ** load precompiled Lua chunks ** See Copyright Notice in lua.h */ @@ -23,8 +23,7 @@ #define LUAC_FORMAT 0 /* this is the official format */ /* load one chunk; from lundump.c */ -LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, - const char* name); +LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name); /* dump one chunk; from ldump.c */ LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, diff --git a/source/extern/lua/lutf8lib.c b/source/extern/lua/lutf8lib.c index 9042582..10bd238 100644 --- a/source/extern/lua/lutf8lib.c +++ b/source/extern/lua/lutf8lib.c @@ -1,5 +1,5 @@ /* -** $Id: lutf8lib.c,v 1.15 2015/03/28 19:16:55 roberto Exp $ +** $Id: lutf8lib.c,v 1.16.1.1 2017/04/19 17:29:57 roberto Exp $ ** Standard library for UTF-8 manipulation ** See Copyright Notice in lua.h */ @@ -171,7 +171,7 @@ static int byteoffset (lua_State *L) { } else { if (iscont(s + posi)) - luaL_error(L, "initial position is a continuation byte"); + return luaL_error(L, "initial position is a continuation byte"); if (n < 0) { while (n < 0 && posi > 0) { /* move back */ do { /* find beginning of previous character */ @@ -194,7 +194,7 @@ static int byteoffset (lua_State *L) { lua_pushinteger(L, posi + 1); else /* no such character */ lua_pushnil(L); - return 1; + return 1; } diff --git a/source/extern/lua/lvm.c b/source/extern/lua/lvm.c index a8cefc5..cc43d87 100644 --- a/source/extern/lua/lvm.c +++ b/source/extern/lua/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 2.245 2015/06/09 15:53:35 roberto Exp $ +** $Id: lvm.c,v 2.268.1.1 2017/04/19 17:39:34 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -153,75 +153,88 @@ static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step, /* -** Main function for table access (invoking metamethods if needed). -** Compute 'val = t[key]' +** Finish the table access 'val = t[key]'. +** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to +** t[k] entry (which must be nil). */ -void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { +void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, + const TValue *slot) { int loop; /* counter to avoid infinite loops */ + const TValue *tm; /* metamethod */ for (loop = 0; loop < MAXTAGLOOP; loop++) { - const TValue *tm; - if (ttistable(t)) { /* 't' is a table? */ - Table *h = hvalue(t); - const TValue *res = luaH_get(h, key); /* do a primitive get */ - if (!ttisnil(res) || /* result is not nil? */ - (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ - setobj2s(L, val, res); /* result is the raw get */ + if (slot == NULL) { /* 't' is not a table? */ + lua_assert(!ttistable(t)); + tm = luaT_gettmbyobj(L, t, TM_INDEX); + if (ttisnil(tm)) + luaG_typeerror(L, t, "index"); /* no metamethod */ + /* else will try the metamethod */ + } + else { /* 't' is a table */ + lua_assert(ttisnil(slot)); + tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */ + if (tm == NULL) { /* no metamethod? */ + setnilvalue(val); /* result is nil */ return; } - /* else will try metamethod */ + /* else will try the metamethod */ } - else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) - luaG_typeerror(L, t, "index"); /* no metamethod */ - if (ttisfunction(tm)) { /* metamethod is a function */ - luaT_callTM(L, tm, t, key, val, 1); + if (ttisfunction(tm)) { /* is metamethod a function? */ + luaT_callTM(L, tm, t, key, val, 1); /* call it */ return; } - t = tm; /* else repeat access over 'tm' */ + t = tm; /* else try to access 'tm[key]' */ + if (luaV_fastget(L,t,key,slot,luaH_get)) { /* fast track? */ + setobj2s(L, val, slot); /* done */ + return; + } + /* else repeat (tail call 'luaV_finishget') */ } - luaG_runerror(L, "gettable chain too long; possible loop"); + luaG_runerror(L, "'__index' chain too long; possible loop"); } /* -** Main function for table assignment (invoking metamethods if needed). -** Compute 't[key] = val' +** Finish a table assignment 't[key] = val'. +** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points +** to the entry 't[key]', or to 'luaO_nilobject' if there is no such +** entry. (The value at 'slot' must be nil, otherwise 'luaV_fastset' +** would have done the job.) */ -void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { +void luaV_finishset (lua_State *L, const TValue *t, TValue *key, + StkId val, const TValue *slot) { int loop; /* counter to avoid infinite loops */ for (loop = 0; loop < MAXTAGLOOP; loop++) { - const TValue *tm; - if (ttistable(t)) { /* 't' is a table? */ - Table *h = hvalue(t); - TValue *oldval = cast(TValue *, luaH_get(h, key)); - /* if previous value is not nil, there must be a previous entry - in the table; a metamethod has no relevance */ - if (!ttisnil(oldval) || - /* previous value is nil; must check the metamethod */ - ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL && - /* no metamethod; is there a previous entry in the table? */ - (oldval != luaO_nilobject || - /* no previous entry; must create one. (The next test is - always true; we only need the assignment.) */ - (oldval = luaH_newkey(L, h, key), 1)))) { + const TValue *tm; /* '__newindex' metamethod */ + if (slot != NULL) { /* is 't' a table? */ + Table *h = hvalue(t); /* save 't' table */ + lua_assert(ttisnil(slot)); /* old value must be nil */ + tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ + if (tm == NULL) { /* no metamethod? */ + if (slot == luaO_nilobject) /* no previous entry? */ + slot = luaH_newkey(L, h, key); /* create one */ /* no metamethod and (now) there is an entry with given key */ - setobj2t(L, oldval, val); /* assign new value to that entry */ + setobj2t(L, cast(TValue *, slot), val); /* set its new value */ invalidateTMcache(h); luaC_barrierback(L, h, val); return; } /* else will try the metamethod */ } - else /* not a table; check metamethod */ + else { /* not a table; check metamethod */ if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) luaG_typeerror(L, t, "index"); + } /* try the metamethod */ if (ttisfunction(tm)) { luaT_callTM(L, tm, t, key, val, 0); return; } t = tm; /* else repeat assignment over 'tm' */ + if (luaV_fastset(L, t, key, slot, luaH_get, val)) + return; /* done */ + /* else loop */ } - luaG_runerror(L, "settable chain too long; possible loop"); + luaG_runerror(L, "'__newindex' chain too long; possible loop"); } @@ -443,6 +456,17 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { #define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0) +/* copy strings in stack from top - n up to top - 1 to buffer */ +static void copy2buff (StkId top, int n, char *buff) { + size_t tl = 0; /* size already copied */ + do { + size_t l = vslen(top - n); /* length of string being copied */ + memcpy(buff + tl, svalue(top - n), l * sizeof(char)); + tl += l; + } while (--n > 0); +} + + /* ** Main operation for concatenation: concat 'total' values in the stack, ** from 'L->top - total' up to 'L->top - 1'. @@ -462,24 +486,24 @@ void luaV_concat (lua_State *L, int total) { else { /* at least two non-empty string values; get as many as possible */ size_t tl = vslen(top - 1); - char *buffer; - int i; - /* collect total length */ - for (i = 1; i < total && tostring(L, top-i-1); i++) { - size_t l = vslen(top - i - 1); + TString *ts; + /* collect total length and number of strings */ + for (n = 1; n < total && tostring(L, top - n - 1); n++) { + size_t l = vslen(top - n - 1); if (l >= (MAX_SIZE/sizeof(char)) - tl) luaG_runerror(L, "string length overflow"); tl += l; } - buffer = luaZ_openspace(L, &G(L)->buff, tl); - tl = 0; - n = i; - do { /* copy all strings to buffer */ - size_t l = vslen(top - i); - memcpy(buffer+tl, svalue(top-i), l * sizeof(char)); - tl += l; - } while (--i > 0); - setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); /* create result */ + if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */ + char buff[LUAI_MAXSHORTLEN]; + copy2buff(top, n, buff); /* copy strings to buffer */ + ts = luaS_newlstr(L, buff, tl); + } + else { /* long string; copy strings directly to final result */ + ts = luaS_createlngstrobj(L, tl); + copy2buff(top, n, getstr(ts)); + } + setsvalue2s(L, top - n, ts); /* create result */ } total -= n-1; /* got 'n' strings to create 1 new */ L->top -= n-1; /* popped 'n' strings and pushed one */ @@ -700,27 +724,20 @@ void luaV_finishOp (lua_State *L) { ** some macros for common tasks in 'luaV_execute' */ -#if !defined(luai_runtimecheck) -#define luai_runtimecheck(L, c) /* void */ -#endif - #define RA(i) (base+GETARG_A(i)) -/* to be used after possible stack reallocation */ #define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) #define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) #define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) #define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) -#define KBx(i) \ - (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++))) /* execute a jump instruction */ #define dojump(ci,i,e) \ { int a = GETARG_A(i); \ - if (a > 0) luaF_close(L, ci->u.l.base + a - 1); \ + if (a != 0) luaF_close(L, ci->u.l.base + a - 1); \ ci->u.l.savedpc += GETARG_sBx(i) + e; } /* for test instructions, execute the jump instruction that follows it */ @@ -730,38 +747,58 @@ void luaV_finishOp (lua_State *L) { #define Protect(x) { {x;}; base = ci->u.l.base; } #define checkGC(L,c) \ - Protect( luaC_condGC(L,{L->top = (c); /* limit of live values */ \ - luaC_step(L); \ - L->top = ci->top;}) /* restore top */ \ - luai_threadyield(L); ) + { luaC_condGC(L, L->top = (c), /* limit of live values */ \ + Protect(L->top = ci->top)); /* restore top */ \ + luai_threadyield(L); } +/* fetch an instruction and prepare its execution */ +#define vmfetch() { \ + i = *(ci->u.l.savedpc++); \ + if (L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) \ + Protect(luaG_traceexec(L)); \ + ra = RA(i); /* WARNING: any stack reallocation invalidates 'ra' */ \ + lua_assert(base == ci->u.l.base); \ + lua_assert(base <= L->top && L->top < L->stack + L->stacksize); \ +} + #define vmdispatch(o) switch(o) #define vmcase(l) case l: #define vmbreak break + +/* +** copy of 'luaV_gettable', but protecting the call to potential +** metamethod (which can reallocate the stack) +*/ +#define gettableProtected(L,t,k,v) { const TValue *slot; \ + if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \ + else Protect(luaV_finishget(L,t,k,v,slot)); } + + +/* same for 'luaV_settable' */ +#define settableProtected(L,t,k,v) { const TValue *slot; \ + if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \ + Protect(luaV_finishset(L,t,k,v,slot)); } + + + void luaV_execute (lua_State *L) { CallInfo *ci = L->ci; LClosure *cl; TValue *k; StkId base; + ci->callstatus |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */ newframe: /* reentry point when frame changes (call/return) */ lua_assert(ci == L->ci); - cl = clLvalue(ci->func); - k = cl->p->k; - base = ci->u.l.base; + cl = clLvalue(ci->func); /* local reference to function's closure */ + k = cl->p->k; /* local reference to function's constant table */ + base = ci->u.l.base; /* local copy of function's base */ /* main loop of interpreter */ for (;;) { - Instruction i = *(ci->u.l.savedpc++); + Instruction i; StkId ra; - if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && - (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { - Protect(luaG_traceexec(L)); - } - /* WARNING: several calls may realloc the stack and invalidate 'ra' */ - ra = RA(i); - lua_assert(base == ci->u.l.base); - lua_assert(base <= L->top && L->top < L->stack + L->stacksize); + vmfetch(); vmdispatch (GET_OPCODE(i)) { vmcase(OP_MOVE) { setobjs2s(L, ra, RB(i)); @@ -797,17 +834,22 @@ void luaV_execute (lua_State *L) { vmbreak; } vmcase(OP_GETTABUP) { - int b = GETARG_B(i); - Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra)); + TValue *upval = cl->upvals[GETARG_B(i)]->v; + TValue *rc = RKC(i); + gettableProtected(L, upval, rc, ra); vmbreak; } vmcase(OP_GETTABLE) { - Protect(luaV_gettable(L, RB(i), RKC(i), ra)); + StkId rb = RB(i); + TValue *rc = RKC(i); + gettableProtected(L, rb, rc, ra); vmbreak; } vmcase(OP_SETTABUP) { - int a = GETARG_A(i); - Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i))); + TValue *upval = cl->upvals[GETARG_A(i)]->v; + TValue *rb = RKB(i); + TValue *rc = RKC(i); + settableProtected(L, upval, rb, rc); vmbreak; } vmcase(OP_SETUPVAL) { @@ -817,7 +859,9 @@ void luaV_execute (lua_State *L) { vmbreak; } vmcase(OP_SETTABLE) { - Protect(luaV_settable(L, ra, RKB(i), RKC(i))); + TValue *rb = RKB(i); + TValue *rc = RKC(i); + settableProtected(L, ra, rb, rc); vmbreak; } vmcase(OP_NEWTABLE) { @@ -831,9 +875,15 @@ void luaV_execute (lua_State *L) { vmbreak; } vmcase(OP_SELF) { + const TValue *aux; StkId rb = RB(i); - setobjs2s(L, ra+1, rb); - Protect(luaV_gettable(L, rb, RKC(i), ra)); + TValue *rc = RKC(i); + TString *key = tsvalue(rc); /* key must be a string */ + setobjs2s(L, ra + 1, rb); + if (luaV_fastget(L, rb, key, aux, luaH_getstr)) { + setobj2s(L, ra, aux); + } + else Protect(luaV_finishget(L, rb, rc, ra, aux)); vmbreak; } vmcase(OP_ADD) { @@ -1020,7 +1070,7 @@ void luaV_execute (lua_State *L) { StkId rb; L->top = base + c + 1; /* mark the end of concat operands */ Protect(luaV_concat(L, c - b + 1)); - ra = RA(i); /* 'luav_concat' may invoke TMs and move the stack */ + ra = RA(i); /* 'luaV_concat' may invoke TMs and move the stack */ rb = base + b; setobjs2s(L, ra, rb); checkGC(L, (ra >= rb ? ra + 1 : rb)); @@ -1035,7 +1085,7 @@ void luaV_execute (lua_State *L) { TValue *rb = RKB(i); TValue *rc = RKC(i); Protect( - if (cast_int(luaV_equalobj(L, rb, rc)) != GETARG_A(i)) + if (luaV_equalobj(L, rb, rc) != GETARG_A(i)) ci->u.l.savedpc++; else donextjump(ci); @@ -1082,12 +1132,12 @@ void luaV_execute (lua_State *L) { int nresults = GETARG_C(i) - 1; if (b != 0) L->top = ra+b; /* else previous instruction set top */ if (luaD_precall(L, ra, nresults)) { /* C function? */ - if (nresults >= 0) L->top = ci->top; /* adjust results */ - base = ci->u.l.base; + if (nresults >= 0) + L->top = ci->top; /* adjust results */ + Protect((void)0); /* update 'base' */ } else { /* Lua function */ ci = L->ci; - ci->callstatus |= CIST_REENTRY; goto newframe; /* restart luaV_execute over new Lua function */ } vmbreak; @@ -1096,8 +1146,9 @@ void luaV_execute (lua_State *L) { int b = GETARG_B(i); if (b != 0) L->top = ra+b; /* else previous instruction set top */ lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); - if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */ - base = ci->u.l.base; + if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */ + Protect((void)0); /* update 'base' */ + } else { /* tail call: put called frame (n) in place of caller one (o) */ CallInfo *nci = L->ci; /* called frame */ @@ -1125,8 +1176,8 @@ void luaV_execute (lua_State *L) { vmcase(OP_RETURN) { int b = GETARG_B(i); if (cl->p->sizep > 0) luaF_close(L, base); - b = luaD_poscall(L, ra, (b != 0 ? b - 1 : L->top - ra)); - if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */ + b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra))); + if (ci->callstatus & CIST_FRESH) /* local 'ci' still from callee */ return; /* external invocation: return */ else { /* invocation via reentry: continue execution */ ci = L->ci; @@ -1139,7 +1190,7 @@ void luaV_execute (lua_State *L) { vmcase(OP_FORLOOP) { if (ttisinteger(ra)) { /* integer loop? */ lua_Integer step = ivalue(ra + 2); - lua_Integer idx = ivalue(ra) + step; /* increment index */ + lua_Integer idx = intop(+, ivalue(ra), step); /* increment index */ lua_Integer limit = ivalue(ra + 1); if ((0 < step) ? (idx <= limit) : (limit <= idx)) { ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ @@ -1171,7 +1222,7 @@ void luaV_execute (lua_State *L) { /* all values are integer */ lua_Integer initv = (stopnow ? 0 : ivalue(init)); setivalue(plimit, ilimit); - setivalue(init, initv - ivalue(pstep)); + setivalue(init, intop(-, initv, ivalue(pstep))); } else { /* try making all values floats */ lua_Number ninit; lua_Number nlimit; lua_Number nstep; @@ -1194,7 +1245,7 @@ void luaV_execute (lua_State *L) { setobjs2s(L, cb+1, ra+1); setobjs2s(L, cb, ra); L->top = cb + 3; /* func. + 2 args (state and index) */ - Protect(luaD_call(L, cb, GETARG_C(i), 1)); + Protect(luaD_call(L, cb, GETARG_C(i))); L->top = ci->top; i = *(ci->u.l.savedpc++); /* go to next instruction */ ra = RA(i); @@ -1219,11 +1270,10 @@ void luaV_execute (lua_State *L) { lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); c = GETARG_Ax(*ci->u.l.savedpc++); } - luai_runtimecheck(L, ttistable(ra)); h = hvalue(ra); last = ((c-1)*LFIELDS_PER_FLUSH) + n; if (last > h->sizearray) /* needs more space? */ - luaH_resizearray(L, h, last); /* pre-allocate it at once */ + luaH_resizearray(L, h, last); /* preallocate it at once */ for (; n > 0; n--) { TValue *val = ra+n; luaH_setint(L, h, last--, val); @@ -1243,23 +1293,21 @@ void luaV_execute (lua_State *L) { vmbreak; } vmcase(OP_VARARG) { - int b = GETARG_B(i) - 1; + int b = GETARG_B(i) - 1; /* required results */ int j; int n = cast_int(base - ci->func) - cl->p->numparams - 1; + if (n < 0) /* less arguments than parameters? */ + n = 0; /* no vararg arguments */ if (b < 0) { /* B == 0? */ b = n; /* get all var. arguments */ Protect(luaD_checkstack(L, n)); ra = RA(i); /* previous call may change the stack */ L->top = ra + n; } - for (j = 0; j < b; j++) { - if (j < n) { - setobjs2s(L, ra + j, base - n + j); - } - else { - setnilvalue(ra + j); - } - } + for (j = 0; j < b && j < n; j++) + setobjs2s(L, ra + j, base - n + j); + for (; j < b; j++) /* complete required results with nil */ + setnilvalue(ra + j); vmbreak; } vmcase(OP_EXTRAARG) { diff --git a/source/extern/lua/lvm.h b/source/extern/lua/lvm.h index 0613826..a8f954f 100644 --- a/source/extern/lua/lvm.h +++ b/source/extern/lua/lvm.h @@ -1,5 +1,5 @@ /* -** $Id: lvm.h,v 2.35 2015/02/20 14:27:53 roberto Exp $ +** $Id: lvm.h,v 2.41.1.1 2017/04/19 17:20:42 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -48,15 +48,60 @@ #define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) +/* +** fast track for 'gettable': if 't' is a table and 't[k]' is not nil, +** return 1 with 'slot' pointing to 't[k]' (final result). Otherwise, +** return 0 (meaning it will have to check metamethod) with 'slot' +** pointing to a nil 't[k]' (if 't' is a table) or NULL (otherwise). +** 'f' is the raw get function to use. +*/ +#define luaV_fastget(L,t,k,slot,f) \ + (!ttistable(t) \ + ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ + : (slot = f(hvalue(t), k), /* else, do raw access */ \ + !ttisnil(slot))) /* result not nil? */ + +/* +** standard implementation for 'gettable' +*/ +#define luaV_gettable(L,t,k,v) { const TValue *slot; \ + if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \ + else luaV_finishget(L,t,k,v,slot); } + + +/* +** Fast track for set table. If 't' is a table and 't[k]' is not nil, +** call GC barrier, do a raw 't[k]=v', and return true; otherwise, +** return false with 'slot' equal to NULL (if 't' is not a table) or +** 'nil'. (This is needed by 'luaV_finishget'.) Note that, if the macro +** returns true, there is no need to 'invalidateTMcache', because the +** call is not creating a new entry. +*/ +#define luaV_fastset(L,t,k,slot,f,v) \ + (!ttistable(t) \ + ? (slot = NULL, 0) \ + : (slot = f(hvalue(t), k), \ + ttisnil(slot) ? 0 \ + : (luaC_barrierback(L, hvalue(t), v), \ + setobj2t(L, cast(TValue *,slot), v), \ + 1))) + + +#define luaV_settable(L,t,k,v) { const TValue *slot; \ + if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \ + luaV_finishset(L,t,k,v,slot); } + + + LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode); -LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, - StkId val); -LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, - StkId val); +LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, + StkId val, const TValue *slot); +LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, + StkId val, const TValue *slot); LUAI_FUNC void luaV_finishOp (lua_State *L); LUAI_FUNC void luaV_execute (lua_State *L); LUAI_FUNC void luaV_concat (lua_State *L, int total); diff --git a/source/extern/lua/lzio.c b/source/extern/lua/lzio.c index 4649392..6f79094 100644 --- a/source/extern/lua/lzio.c +++ b/source/extern/lua/lzio.c @@ -1,5 +1,5 @@ /* -** $Id: lzio.c,v 1.36 2014/11/02 19:19:04 roberto Exp $ +** $Id: lzio.c,v 1.37.1.1 2017/04/19 17:20:42 roberto Exp $ ** Buffered streams ** See Copyright Notice in lua.h */ @@ -66,13 +66,3 @@ size_t luaZ_read (ZIO *z, void *b, size_t n) { return 0; } -/* ------------------------------------------------------------------------ */ -char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { - if (n > buff->buffsize) { - if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; - luaZ_resizebuffer(L, buff, n); - } - return buff->buffer; -} - - diff --git a/source/extern/lua/lzio.h b/source/extern/lua/lzio.h index b2e56bc..d897870 100644 --- a/source/extern/lua/lzio.h +++ b/source/extern/lua/lzio.h @@ -1,5 +1,5 @@ /* -** $Id: lzio.h,v 1.30 2014/12/19 17:26:14 roberto Exp $ +** $Id: lzio.h,v 1.31.1.1 2017/04/19 17:20:42 roberto Exp $ ** Buffered streams ** See Copyright Notice in lua.h */ @@ -44,7 +44,6 @@ typedef struct Mbuffer { #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) -LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data); LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ diff --git a/source/extern/luaconf.h b/source/extern/luaconf.h index 7cfa4fa..9eeeea6 100644 --- a/source/extern/luaconf.h +++ b/source/extern/luaconf.h @@ -1,5 +1,5 @@ /* -** $Id: luaconf.h,v 1.251 2015/05/20 17:39:23 roberto Exp $ +** $Id: luaconf.h,v 1.259.1.1 2017/04/19 17:29:57 roberto Exp $ ** Configuration file for Lua ** See Copyright Notice in lua.h */ @@ -145,7 +145,7 @@ #if !defined(LUA_FLOAT_TYPE) #define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE -#endif /* } */ +#endif /* }================================================================== */ @@ -158,6 +158,18 @@ ** =================================================================== */ +/* +** LUA_PATH_SEP is the character that separates templates in a path. +** LUA_PATH_MARK is the string that marks the substitution points in a +** template. +** LUA_EXEC_DIR in a Windows path is replaced by the executable's +** directory. +*/ +#define LUA_PATH_SEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXEC_DIR "!" + + /* @@ LUA_PATH_DEFAULT is the default path that Lua uses to look for ** Lua libraries. @@ -404,7 +416,7 @@ /* @@ LUA_NUMBER is the floating-point type used by Lua. -@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' +@@ LUAI_UACNUMBER is the result of a 'default argument promotion' @@ over a floating number. @@ l_mathlim(x) corrects limit name 'x' to the proper float type ** by prefixing it with one of FLT/DBL/LDBL. @@ -412,9 +424,34 @@ @@ LUA_NUMBER_FMT is the format for writing floats. @@ lua_number2str converts a float to a string. @@ l_mathop allows the addition of an 'l' or 'f' to all math operations. +@@ l_floor takes the floor of a float. @@ lua_str2number converts a decimal numeric string to a number. */ + +/* The following definitions are good for most cases here */ + +#define l_floor(x) (l_mathop(floor)(x)) + +#define lua_number2str(s,sz,n) \ + l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n)) + +/* +@@ lua_numbertointeger converts a float number to an integer, or +** returns 0 if float is not within the range of a lua_Integer. +** (The range comparisons are tricky because of rounding. The tests +** here assume a two-complement representation, where MININTEGER always +** has an exact representation as a float; MAXINTEGER may not have one, +** and therefore its conversion to float may have an ill-defined value.) +*/ +#define lua_numbertointeger(n,p) \ + ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \ + (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \ + (*(p) = (LUA_INTEGER)(n), 1)) + + +/* now the variable definitions */ + #if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT /* { single float */ #define LUA_NUMBER float @@ -468,32 +505,13 @@ #endif /* } */ -#define l_floor(x) (l_mathop(floor)(x)) - -#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) - - -/* -@@ lua_numbertointeger converts a float number to an integer, or -** returns 0 if float is not within the range of a lua_Integer. -** (The range comparisons are tricky because of rounding. The tests -** here assume a two-complement representation, where MININTEGER always -** has an exact representation as a float; MAXINTEGER may not have one, -** and therefore its conversion to float may have an ill-defined value.) -*/ -#define lua_numbertointeger(n,p) \ - ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \ - (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \ - (*(p) = (LUA_INTEGER)(n), 1)) - - /* @@ LUA_INTEGER is the integer type used by Lua. ** @@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER. ** -@@ LUAI_UACINT is the result of an 'usual argument conversion' +@@ LUAI_UACINT is the result of a 'default argument promotion' @@ over a lUA_INTEGER. @@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers. @@ LUA_INTEGER_FMT is the format for writing integers. @@ -506,10 +524,12 @@ /* The following definitions are good for most cases here */ #define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d" -#define lua_integer2str(s,n) sprintf((s), LUA_INTEGER_FMT, (n)) #define LUAI_UACINT LUA_INTEGER +#define lua_integer2str(s,sz,n) \ + l_sprintf((s), sz, LUA_INTEGER_FMT, (LUAI_UACINT)(n)) + /* ** use LUAI_UACINT here to avoid problems with promotions (which ** can turn a comparison between unsigneds into a signed comparison) @@ -537,6 +557,7 @@ #elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */ +/* use presence of macro LLONG_MAX as proxy for C99 compliance */ #if defined(LLONG_MAX) /* { */ /* use ISO C99 stuff */ @@ -577,6 +598,17 @@ ** =================================================================== */ +/* +@@ l_sprintf is equivalent to 'snprintf' or 'sprintf' in C89. +** (All uses in Lua have only one format item.) +*/ +#if !defined(LUA_USE_C89) +#define l_sprintf(s,sz,f,i) snprintf(s,sz,f,i) +#else +#define l_sprintf(s,sz,f,i) ((void)(sz), sprintf(s,f,i)) +#endif + + /* @@ lua_strx2number converts an hexadecimal numeric string to a number. ** In C99, 'strtod' does that conversion. Otherwise, you can @@ -584,18 +616,26 @@ ** implementation. */ #if !defined(LUA_USE_C89) -#define lua_strx2number(s,p) lua_str2number(s,p) +#define lua_strx2number(s,p) lua_str2number(s,p) #endif /* -@@ lua_number2strx converts a float to an hexadecimal numeric string. +@@ lua_pointer2str converts a pointer to a readable string in a +** non-specified way. +*/ +#define lua_pointer2str(buff,sz,p) l_sprintf(buff,sz,"%p",p) + + +/* +@@ lua_number2strx converts a float to an hexadecimal numeric string. ** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that. ** Otherwise, you can leave 'lua_number2strx' undefined and Lua will ** provide its own implementation. */ #if !defined(LUA_USE_C89) -#define lua_number2strx(L,b,f,n) sprintf(b,f,n) +#define lua_number2strx(L,b,sz,f,n) \ + ((void)L, l_sprintf(b,sz,f,(LUAI_UACNUMBER)(n))) #endif @@ -711,11 +751,11 @@ /* @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. ** CHANGE it if it uses too much C-stack space. (For long double, -** 'string.format("%.99f", 1e4932)' needs ~5030 bytes, so a +** 'string.format("%.99f", -1e4932)' needs 5034 bytes, so a ** smaller buffer would force a memory allocation for each call to ** 'string.format'.) */ -#if defined(LUA_FLOAT_LONGDOUBLE) +#if LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE #define LUAL_BUFFERSIZE 8192 #else #define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer))) diff --git a/source/extern/lualib.h b/source/extern/lualib.h index 5165c0f..f5304aa 100644 --- a/source/extern/lualib.h +++ b/source/extern/lualib.h @@ -1,5 +1,5 @@ /* -** $Id: lualib.h,v 1.44 2014/02/06 17:32:33 roberto Exp $ +** $Id: lualib.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $ ** Lua standard libraries ** See Copyright Notice in lua.h */ @@ -11,6 +11,9 @@ #include "lua.h" +/* version suffix for environment variable names */ +#define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR + LUAMOD_API int (luaopen_base) (lua_State *L); From c47bceb3f3ea0d041f3a6cb053f932c00c39f396 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sun, 5 Jan 2025 15:21:27 +1100 Subject: [PATCH 169/181] add time played support to server query results --- source/game/StarServerClientContext.cpp | 6 ++++++ source/game/StarServerClientContext.hpp | 3 +++ source/game/StarUniverseServer.cpp | 9 +++++++++ source/game/StarUniverseServer.hpp | 1 + source/server/StarServerQueryThread.cpp | 10 ++++++---- source/server/StarServerQueryThread.hpp | 11 ++++++----- 6 files changed, 31 insertions(+), 9 deletions(-) diff --git a/source/game/StarServerClientContext.cpp b/source/game/StarServerClientContext.cpp index fcbffbd..cd7c6cd 100644 --- a/source/game/StarServerClientContext.cpp +++ b/source/game/StarServerClientContext.cpp @@ -63,6 +63,8 @@ ServerClientContext::ServerClientContext(ConnectionId clientId, Maybe const m_remoteAddress; @@ -109,6 +111,7 @@ private: NetElementTopGroup m_netGroup; uint64_t m_netVersion = 0; + int64_t m_creationTime; NetElementData>> m_orbitWarpActionNetState; NetElementData m_playerWorldIdNetState; diff --git a/source/game/StarUniverseServer.cpp b/source/game/StarUniverseServer.cpp index 9ce097e..fde8ca6 100644 --- a/source/game/StarUniverseServer.cpp +++ b/source/game/StarUniverseServer.cpp @@ -173,6 +173,15 @@ List UniverseServer::clientIds() const { return m_clients.keys(); } +List> UniverseServer::clientIdsAndCreationTime() const { + List> result; + ReadLocker clientsLocker(m_clientsLock); + result.reserve(m_clients.size()); + for (auto& pair : m_clients) + result.emplaceAppend(pair.first, pair.second->creationTime()); + return result; +} + size_t UniverseServer::numberOfClients() const { ReadLocker clientsLocker(m_clientsLock); return m_clients.size(); diff --git a/source/game/StarUniverseServer.hpp b/source/game/StarUniverseServer.hpp index e7f24fa..a87194f 100644 --- a/source/game/StarUniverseServer.hpp +++ b/source/game/StarUniverseServer.hpp @@ -55,6 +55,7 @@ public: bool isWorldActive(WorldId const& worldId) const; List clientIds() const; + List> clientIdsAndCreationTime() const; size_t numberOfClients() const; uint32_t maxClients() const; bool isConnectedClient(ConnectionId clientId) const; diff --git a/source/server/StarServerQueryThread.cpp b/source/server/StarServerQueryThread.cpp index 2011f42..441fa63 100644 --- a/source/server/StarServerQueryThread.cpp +++ b/source/server/StarServerQueryThread.cpp @@ -107,6 +107,8 @@ bool ServerQueryThread::processPacket(HostAddressWithPort const& address, char c << A2S_TYPE_DEDICATED // dedicated #ifdef STAR_SYSTEM_FAMILY_WINDOWS << A2S_ENV_WINDOWS // os +#elif defined(STAR_SYSTEM_MACOS) + << A2S_ENV_MAC // os #else << A2S_ENV_LINUX // os #endif @@ -153,17 +155,17 @@ void ServerQueryThread::buildPlayerResponse() { return; } - auto clientIds = m_universe->clientIds(); + auto clientIds = m_universe->clientIdsAndCreationTime(); uint8_t cnt = (uint8_t)clientIds.count(); int32_t kills = 0; // Not currently supported - float timeConnected = 60; // Not supported defaults to 1min m_playersResponse.clear(); m_playersResponse << A2S_HEAD_INT << A2S_PLAYER_REPLY << cnt; uint8_t i = 0; - for (auto clientId : clientIds) { - m_playersResponse << i++ << m_universe->clientNick(clientId) << kills << timeConnected; + for (auto& pair : clientIds) { + auto timeConnected = float(now - pair.second) / 1000.f; + m_playersResponse << i++ << m_universe->clientNick(pair.first) << kills << timeConnected; } m_lastPlayersResponse = now; diff --git a/source/server/StarServerQueryThread.hpp b/source/server/StarServerQueryThread.hpp index 54ab93f..d45e1a9 100644 --- a/source/server/StarServerQueryThread.hpp +++ b/source/server/StarServerQueryThread.hpp @@ -42,11 +42,12 @@ private: static const uint8_t A2S_EDF_TAGS = 0x20; static const uint8_t A2S_EDF_STV = 0x40; static const uint8_t A2S_EDF_PORT = 0x80; - static const uint8_t A2S_ENV_WINDOWS = 'W'; - static const uint8_t A2S_ENV_LINUX = 'L'; - static const uint8_t A2S_TYPE_DEDICATED = 'D'; - static const uint8_t A2S_TYPE_LISTEN = 'L'; - static const uint8_t A2S_TYPE_TV = 'P'; + static const uint8_t A2S_ENV_WINDOWS = 'w'; + static const uint8_t A2S_ENV_LINUX = 'l'; + static const uint8_t A2S_ENV_MAC = 'm'; + static const uint8_t A2S_TYPE_DEDICATED = 'd'; + static const uint8_t A2S_TYPE_LISTEN = 'l'; + static const uint8_t A2S_TYPE_TV = 'p'; static const uint8_t A2S_VAC_OFF = 0x00; static const uint8_t A2S_VAC_ON = 0x01; static constexpr const char* A2S_INFO_REQUEST_STRING = "Source Engine Query"; From 57a5afa13a027429c2758582ba1f581d0272fcc4 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sun, 5 Jan 2025 15:21:59 +1100 Subject: [PATCH 170/181] fix net compat rules not being considered in client netLoad --- source/game/StarWorldClient.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/game/StarWorldClient.cpp b/source/game/StarWorldClient.cpp index 6f0f2af..efc2eb7 100644 --- a/source/game/StarWorldClient.cpp +++ b/source/game/StarWorldClient.cpp @@ -771,8 +771,9 @@ void WorldClient::handleIncomingPackets(List const& packets) { removeEntity(entityCreate->entityId, false); } - auto entity = entityFactory->netLoadEntity(entityCreate->entityType, entityCreate->storeData); - entity->readNetState(entityCreate->firstNetState, 0.0f, m_clientState.netCompatibilityRules()); + auto netRules = m_clientState.netCompatibilityRules(); + auto entity = entityFactory->netLoadEntity(entityCreate->entityType, entityCreate->storeData, netRules); + entity->readNetState(entityCreate->firstNetState, 0.0f, netRules); entity->init(this, entityCreate->entityId, EntityMode::Slave); m_entityMap->addEntity(entity); From 06ce4f042d1c18cf6806c97653789c414bc5c7b2 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sun, 5 Jan 2025 15:22:20 +1100 Subject: [PATCH 171/181] add version logging for named asset sources --- source/game/StarRoot.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/game/StarRoot.cpp b/source/game/StarRoot.cpp index a260dbb..bda228c 100644 --- a/source/game/StarRoot.cpp +++ b/source/game/StarRoot.cpp @@ -585,6 +585,7 @@ StringList Root::scanForAssetSources(StringList const& directories, StringList c struct AssetSource { String path; Maybe name; + Maybe version; float priority; StringList requires_; StringList includes; @@ -612,6 +613,7 @@ StringList Root::scanForAssetSources(StringList const& directories, StringList c auto assetSource = make_shared(); assetSource->path = sourcePath; assetSource->name = metadata.maybe("name").apply(mem_fn(&Json::toString)); + assetSource->version = metadata.maybe("version").apply(mem_fn(&Json::toString)); assetSource->priority = metadata.value("priority", 0.0f).toFloat(); assetSource->requires_ = jsonToStringList(metadata.value("requires", JsonArray{})); assetSource->includes = jsonToStringList(metadata.value("includes", JsonArray{})); @@ -705,7 +707,7 @@ StringList Root::scanForAssetSources(StringList const& directories, StringList c for (auto const& source : dependencySortedSources) { auto path = File::convertDirSeparators(source->path); if (source->name) - Logger::info("Root: Detected asset source named '{}' at '{}'", *source->name, path); + Logger::info("Root: Detected asset source named '{}'{} at '{}'", *source->name, source->version ? strf(" version '{}'", *source->version) : "", path); else Logger::info("Root: Detected unnamed asset source at '{}'", path); sourcePaths.append(path); From 64df8908642c8d51ad86cf3ec425253502d60bea Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 7 Jan 2025 19:52:29 +1100 Subject: [PATCH 172/181] update unifont also added font sources --- assets/opensb/font/sources.txt | 7 +++++++ assets/opensb/font/unifont.woff2 | Bin 3765804 -> 3774176 bytes 2 files changed, 7 insertions(+) create mode 100644 assets/opensb/font/sources.txt diff --git a/assets/opensb/font/sources.txt b/assets/opensb/font/sources.txt new file mode 100644 index 0000000..6265300 --- /dev/null +++ b/assets/opensb/font/sources.txt @@ -0,0 +1,7 @@ +m6x11: managore.itch.io/m6x11 +beech: 04.jp.org +twemoji: github.com/jdecked/twemoji +unifont: github.com/stgiga/UnifontEX +dotsies: dotsies.org +newspaper: onlygfx.com/newspaper-cutout +pixelhobo: Chucklefish \ No newline at end of file diff --git a/assets/opensb/font/unifont.woff2 b/assets/opensb/font/unifont.woff2 index 5da6c98284efcf7ff8ffa8d5a8deefdbc547d125..3563d52197cc32bb778adbe4c2e7b510d6b75ebd 100644 GIT binary patch literal 3774176 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∫cOcp-otqZE2`) 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≫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Ø-d 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

    8i1o7v81|lNP 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 z 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%0D>^w^w1v^ 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̜y=pRV+-vYT3p|`=-EI+8eFUEYw;DqT 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