diff --git a/.github/codegen/generate-build-native.ws.kts b/.github/codegen/generate-build-native.ws.kts
deleted file mode 100644
index 3e06cee0c..000000000
--- a/.github/codegen/generate-build-native.ws.kts
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-val env = "\${{ env.gradleArgs }}"
-
-val isUbunutu = "\${{ env.isUbuntu == 'true' }}"
-val isWindows = "\${{ env.isWindows == 'true' }}"
-val isMac = "\${{ env.isMac == 'true' }}"
-
-
-val template = """
- - if: CONDITION
- name: "Compile mirai-core-api for macosArm64"
- run: ./gradlew :mirai-core-api:compileKotlinMacosArm64 :mirai-core-api:compileTestKotlinMacosArm64 $env
-
- - if: CONDITION
- name: "Link mirai-core-api for macosArm64"
- run: ./gradlew mirai-core-api:linkDebugTestMacosArm64 $env
-
- - if: CONDITION
- name: "Test mirai-core-api for macosArm64"
- run: ./gradlew :mirai-core-api:macosArm64Test $env
-""".trimIndent()
-
-val output = buildString {
- val title = "############# GENERATED FROM generate-build-native.ws.kts #############"
- appendLine("#".repeat(title.length))
- appendLine(title)
- appendLine("#".repeat(title.length))
- appendLine()
-
-
-
- listOf("mirai-core-utils", "mirai-core-api", "mirai-core").forEach { moduleName ->
- appendLine(
- """
- - name: "Commonize mirai-core-api"
- run: ./gradlew :mirai-core-api:commonize $env
- """.trimIndent().replace("mirai-core-api", moduleName)
- )
- appendLine()
- }
-
- listOf("mirai-core-utils", "mirai-core-api", "mirai-core").forEach { moduleName ->
- appendLine("# $moduleName")
- appendLine()
- appendLine(
- """
- - name: "Compile mirai-core-api for common"
- run: ./gradlew :mirai-core-api:compileCommonMainKotlinMetadata $env
-
- - name: "Compile mirai-core-api for native"
- run: ./gradlew :mirai-core-api:compileNativeMainKotlinMetadata $env
-
- - name: "Compile mirai-core-api for unix-like"
- run: ./gradlew :mirai-core-api:compileUnixMainKotlinMetadata $env
- """.trimIndent().replace("mirai-core-api", moduleName)
- )
- appendLine()
-
- listOf("macosX64" to isMac, "mingwX64" to isWindows, "linuxX64" to isUbunutu).forEach { (target, condition) ->
- appendLine(useTemplate(moduleName, target, condition))
- appendLine()
- appendLine()
- }
- appendLine()
- }
-
- this.trimEnd().let { c -> clear().appendLine(c) } // remove trailing empty lines
-
- appendLine()
- appendLine("#".repeat(title.length))
-}
-println(output.prependIndent(" ".repeat(6)))
-
-fun useTemplate(moduleName: String, target: String, condition: String) = template
- .replace("mirai-core-api", moduleName)
- .replace("macosArm64", target)
- .replace("MacosArm64", target.replaceFirstChar { it.uppercaseChar() })
- .replace("CONDITION", condition)
- // Link release artifacts to save memory
- .replace("linkDebugTestMingwX64", "linkReleaseTestMingwX64")
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 869f122db..bd3f96d87 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -14,8 +14,8 @@ on:
- '**/*.md'
jobs:
- build-mirai-jvm:
- name: "JVM (${{ matrix.os }})"
+ build:
+ name: "Build (${{ matrix.os }})"
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
@@ -24,7 +24,7 @@ jobs:
# - windows-2022
- macos-12
env:
- gradleArgs: --scan "-Dmirai.target=jvm;android;!other" "-Pkotlin.compiler.execution.strategy=in-process" "-Dorg.gradle.jvmargs=-Xmx6000m" "-Dfile.encoding=UTF-8"
+ gradleArgs: --scan
isMac: ${{ startsWith(matrix.os, 'macos') }}
isWindows: ${{ startsWith(matrix.os, 'windows') }}
isUbuntu: ${{ startsWith(matrix.os, 'ubuntu') }}
@@ -77,6 +77,24 @@ jobs:
- name: "Check"
run: ./gradlew check ${{ env.gradleArgs }}
+ # Snapshots
+
+ - if: ${{ env.isMac == 'true' }}
+ name: Ensure KDoc valid
+ run: ./gradlew dokkaHtmlMultiModule ${{ env.gradleArgs }}
+
+ - name: Release RAM
+ run: node ci-release-helper/scripts/kill-java.js
+
+ - name: Publish Snapshots
+ if: ${{ github.event.pusher && env.isMac == 'true' && vars.RUN_MIRAI_SNAPSHOTS == 'true' }}
+ run: ./gradlew publishAllPublicationsToMiraiRepoRepository ${{ env.gradleArgs }}
+ env:
+ MIRAI_IS_SNAPSHOTS_PUBLISHING: true
+ SNAPSHOTS_PUBLISHING_USER: ${{ secrets.SNAPSHOTS_PUBLISHING_USER }}
+ SNAPSHOTS_PUBLISHING_KEY: ${{ secrets.SNAPSHOTS_PUBLISHING_KEY }}
+ SNAPSHOTS_PUBLISHING_URL: ${{ secrets.SNAPSHOTS_PUBLISHING_URL }}
+
# Upload
- name: Upload mirai-core-utils
@@ -156,249 +174,3 @@ jobs:
with:
name: mirai-logging-slf4j-simple
path: logging/mirai-logging-slf4j-simple/build/libs
-
- build-mirai-all:
- name: "Everything (${{ matrix.os }})"
- runs-on: ${{ matrix.os }}
- strategy:
- fail-fast: false
- matrix:
- os:
- - macos-12
- env:
- enableLocalPublishingTest: 'false'
- gradleArgs: --scan
- isMac: ${{ startsWith(matrix.os, 'macos') }}
- isWindows: ${{ startsWith(matrix.os, 'windows') }}
- isUbuntu: ${{ startsWith(matrix.os, 'ubuntu') }}
- isUnix: ${{ startsWith(matrix.os, 'macos') || startsWith(matrix.os, 'ubuntu') }}
- steps:
- - uses: actions/checkout@v3
- with:
- submodules: 'recursive'
-
- - uses: actions/setup-java@v3
- with:
- distribution: 'temurin'
- java-version: '17'
-
- - name: Setup Gradle
- uses: gradle/gradle-build-action@v2
-
- - name: Cache konan
- uses: pat-s/always-upload-cache@v3.0.11
- with:
- path: ~/.konan
- key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
- restore-keys: |
- ${{ runner.os }}-gradle-
-
- - if: ${{ env.isUnix == 'true' }}
- run: chmod -R 777 *
-
- - name: Clean and download dependencies
- run: ./gradlew clean ${{ env.gradleArgs }}
-
- - run: >
- ./gradlew updateSnapshotVersion ${{ env.gradleArgs }}
- if: github.event.pusher && vars.RUN_MIRAI_SNAPSHOTS == 'true'
- env:
- MIRAI_IS_SNAPSHOTS_PUBLISHING: true
- SNAPSHOTS_PUBLISHING_USER: ${{ secrets.SNAPSHOTS_PUBLISHING_USER }}
- SNAPSHOTS_PUBLISHING_KEY: ${{ secrets.SNAPSHOTS_PUBLISHING_KEY }}
- SNAPSHOTS_PUBLISHING_URL: ${{ secrets.SNAPSHOTS_PUBLISHING_URL }}
- MIRAI_BUILD_INDEX_AUTH_USERNAME: ${{ secrets.MIRAI_BUILD_INDEX_AUTH_USERNAME }}
- MIRAI_BUILD_INDEX_AUTH_PASSWORD: ${{ secrets.MIRAI_BUILD_INDEX_AUTH_PASSWORD }}
-
- - name: "Assemble"
- run: ./gradlew assemble ${{ env.gradleArgs }}
-
- - name: Publish Local Artifacts
- if: ${{ env.enableLocalPublishingTest == 'true' }}
- run: ./gradlew :mirai-deps-test:publishMiraiArtifactsToMavenLocal ${{ env.gradleArgs }} "-Dmirai.build.project.version=2.99.0-deps-test"
-
- - name: "Check"
- run: ./gradlew check ${{ env.gradleArgs }}
-
- - if: ${{ env.isMac == 'true' }}
- name: Ensure KDoc valid
- run: ./gradlew dokkaHtmlMultiModule ${{ env.gradleArgs }}
-
- - name: Release RAM
- run: node ci-release-helper/scripts/kill-java.js
-
- - name: Publish Snapshots
- if: ${{ github.event.pusher && env.isMac == 'true' && vars.RUN_MIRAI_SNAPSHOTS == 'true' }}
- run: ./gradlew publishAllPublicationsToMiraiRepoRepository ${{ env.gradleArgs }}
- env:
- MIRAI_IS_SNAPSHOTS_PUBLISHING: true
- SNAPSHOTS_PUBLISHING_USER: ${{ secrets.SNAPSHOTS_PUBLISHING_USER }}
- SNAPSHOTS_PUBLISHING_KEY: ${{ secrets.SNAPSHOTS_PUBLISHING_KEY }}
- SNAPSHOTS_PUBLISHING_URL: ${{ secrets.SNAPSHOTS_PUBLISHING_URL }}
-
- build-mirai-core-native:
- name: "Native (${{ matrix.os }})"
- runs-on: ${{ matrix.os }}
- strategy:
- fail-fast: false
- matrix:
- os:
- - windows-2022
- - ubuntu-20.04
- # - ubuntu-18.04
- # - macos-12
- # - macos-11
- include:
- - os: windows-2022
- targetName: mingwX64
- - os: ubuntu-20.04
- targetName: linuxX64
- # - os: macos-12
- # targetName: macosX64
- # - os: macos-11
- # targetName: macosX64
- env:
- # FIXME there must be two or more targets, or we'll get error on `@OptionalExpectation`
- # > Declaration annotated with '@OptionalExpectation' can only be used in common module sources
- enableLocalPublishingTest: 'false'
- gradleArgs: --scan "-Dmirai.target=jvm;${{ matrix.targetName }};!other" "-Pkotlin.compiler.execution.strategy=in-process" "-Dorg.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8"
- isMac: ${{ startsWith(matrix.os, 'macos') }}
- isWindows: ${{ startsWith(matrix.os, 'windows') }}
- isUbuntu: ${{ startsWith(matrix.os, 'ubuntu') }}
- isUnix: ${{ startsWith(matrix.os, 'macos') || startsWith(matrix.os, 'ubuntu') }}
- VCPKG_DEFAULT_BINARY_CACHE: ${{ startsWith(matrix.os, 'windows') && 'C:\vcpkg\binary_cache' || '/usr/local/share/vcpkg/binary_cache' }}
- steps:
- - uses: actions/checkout@v3
- with:
- submodules: 'recursive'
-
- - uses: actions/setup-java@v3
- with:
- distribution: 'adopt-openj9'
- java-version: '17'
-
- - name: Setup Gradle
- uses: gradle/gradle-build-action@v2
-
- - name: Cache konan
- uses: pat-s/always-upload-cache@v3.0.11
- with:
- path: ~/.konan
- key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
- restore-keys: |
- ${{ runner.os }}-gradle-
-
- - name: Prepare to cache vcpkg
- if: ${{ env.isWindows == 'true' }}
- run: mkdir -p ${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
-
- - name: Cache vcpkg
- if: ${{ env.isWindows == 'true' }}
- uses: pat-s/always-upload-cache@v3.0.11
- with:
- path: ${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
- key: ${{ runner.os }}-vcpkg-binary-cache-${{ github.job }}
- restore-keys: |
- ${{ runner.os }}-vcpkg-binary-cache-
-
- - if: ${{ env.isUnix == 'true' }}
- run: chmod -R 777 *
-
- # Prepare environment for linking on macOS
- - if: ${{ env.isMac == 'true' }}
- name: Install OpenSSL on Mac OS
- run: >
- git clone https://github.com/openssl/openssl.git --recursive &&
- cd openssl &&
- git checkout tags/openssl-3.0.3 &&
- ./Configure --prefix=/opt/openssl --openssldir=/usr/local/ssl &&
- make &&
- sudo make install
-
- # Prepare environment for linking on Ubuntu
- - if: ${{ env.isUbuntu == 'true' }}
- name: Install OpenSSL on Ubuntu
- run: sudo apt install libssl-dev -y
-
- # Prepare environment for linking on Windows
- - if: ${{ env.isWindows == 'true' }}
- name: Setup Memory Environment on Windows
- run: >
- wmic pagefileset where name="D:\\pagefile.sys" set InitialSize=1024,MaximumSize=9216 &
- net stop mongodb
- shell: cmd
- continue-on-error: true
-
- - if: ${{ env.isWindows == 'true' }}
- name: Install OpenSSL & cURL on Windows
- run: |
- echo "set(VCPKG_BUILD_TYPE release)" | Out-File -FilePath "$env:VCPKG_INSTALLATION_ROOT\triplets\x64-windows.cmake" -Encoding utf8 -Append
- vcpkg install openssl:x64-windows curl[core,ssl]:x64-windows
- New-Item -Path $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\crypto.lib -ItemType SymbolicLink -Value $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\libcrypto.lib
- New-Item -Path $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\ssl.lib -ItemType SymbolicLink -Value $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\libssl.lib
- New-Item -Path $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\curl.lib -ItemType SymbolicLink -Value $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\libcurl.lib
- echo "$env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
-
- - name: Clean and download dependencies
- run: ./gradlew clean ${{ env.gradleArgs }}
-
- - run: >
- ./gradlew updateSnapshotVersion ${{ env.gradleArgs }}
- if: github.event.pusher && vars.RUN_MIRAI_SNAPSHOTS == 'true'
- env:
- MIRAI_IS_SNAPSHOTS_PUBLISHING: true
- SNAPSHOTS_PUBLISHING_USER: ${{ secrets.SNAPSHOTS_PUBLISHING_USER }}
- SNAPSHOTS_PUBLISHING_KEY: ${{ secrets.SNAPSHOTS_PUBLISHING_KEY }}
- SNAPSHOTS_PUBLISHING_URL: ${{ secrets.SNAPSHOTS_PUBLISHING_URL }}
- MIRAI_BUILD_INDEX_AUTH_USERNAME: ${{ secrets.MIRAI_BUILD_INDEX_AUTH_USERNAME }}
- MIRAI_BUILD_INDEX_AUTH_PASSWORD: ${{ secrets.MIRAI_BUILD_INDEX_AUTH_PASSWORD }}
-
- - name: "Test mirai-core-utils for ${{ matrix.os }}"
- run: ./gradlew :mirai-core-utils:${{ matrix.targetName }}Test ${{ env.gradleArgs }}
-
- - name: "Test mirai-core-api for ${{ matrix.os }}"
- run: ./gradlew :mirai-core-api:${{ matrix.targetName }}Test ${{ env.gradleArgs }}
-
- - name: "Test mirai-core for ${{ matrix.os }}"
- run: ./gradlew :mirai-core:${{ matrix.targetName }}Test ${{ env.gradleArgs }}
-
- - name: Publish Local Artifacts
- if: ${{ env.enableLocalPublishingTest == 'true' }}
- run: ./gradlew :mirai-deps-test:publishMiraiArtifactsToMavenLocal ${{ env.gradleArgs }} "-Dmirai.build.project.version=2.99.0-deps-test"
-
- - name: Check Publication
- if: ${{ env.enableLocalPublishingTest == 'true' }}
- run: ./gradlew :mirai-deps-test:check ${{ env.gradleArgs }}
-
- # Publish native snapshots. Other artifacts are published in build-mirai-all
-
- - name: Release RAM
- run: node ci-release-helper/scripts/kill-java.js
-
- - name: Publish MingwX64 Snapshots
- if: ${{ github.event.pusher && env.isWindows == 'true' && vars.RUN_MIRAI_SNAPSHOTS == 'true' }}
- run: ./gradlew publishMingwX64PublicationToMiraiRepoRepository ${{ env.gradleArgs }}
- env:
- MIRAI_IS_SNAPSHOTS_PUBLISHING: true
- SNAPSHOTS_PUBLISHING_USER: ${{ secrets.SNAPSHOTS_PUBLISHING_USER }}
- SNAPSHOTS_PUBLISHING_KEY: ${{ secrets.SNAPSHOTS_PUBLISHING_KEY }}
- SNAPSHOTS_PUBLISHING_URL: ${{ secrets.SNAPSHOTS_PUBLISHING_URL }}
-
- - name: Publish LinuxX64 Snapshots
- if: ${{ github.event.pusher && env.isUbuntu == 'true' && vars.RUN_MIRAI_SNAPSHOTS == 'true' }}
- run: ./gradlew publishLinuxX64PublicationToMiraiRepoRepository ${{ env.gradleArgs }}
- env:
- MIRAI_IS_SNAPSHOTS_PUBLISHING: true
- SNAPSHOTS_PUBLISHING_USER: ${{ secrets.SNAPSHOTS_PUBLISHING_USER }}
- SNAPSHOTS_PUBLISHING_KEY: ${{ secrets.SNAPSHOTS_PUBLISHING_KEY }}
- SNAPSHOTS_PUBLISHING_URL: ${{ secrets.SNAPSHOTS_PUBLISHING_URL }}
-
- - name: Publish macOSX64 Snapshots
- if: ${{ github.event.pusher && env.isMac == 'true' && vars.RUN_MIRAI_SNAPSHOTS == 'true' }}
- run: ./gradlew publishMacosX64PublicationToMiraiRepoRepository ${{ env.gradleArgs }}
- env:
- MIRAI_IS_SNAPSHOTS_PUBLISHING: true
- SNAPSHOTS_PUBLISHING_USER: ${{ secrets.SNAPSHOTS_PUBLISHING_USER }}
- SNAPSHOTS_PUBLISHING_KEY: ${{ secrets.SNAPSHOTS_PUBLISHING_KEY }}
- SNAPSHOTS_PUBLISHING_URL: ${{ secrets.SNAPSHOTS_PUBLISHING_URL }}
-
diff --git a/.github/workflows/check-publishing.yml b/.github/workflows/check-publishing.yml
index d671c6087..fbb239b97 100644
--- a/.github/workflows/check-publishing.yml
+++ b/.github/workflows/check-publishing.yml
@@ -25,7 +25,7 @@ jobs:
fail-fast: false
matrix:
os:
-# - windows-2022
+ # - windows-2022 # OOM
- ubuntu-20.04
- macos-12
include:
@@ -41,7 +41,7 @@ jobs:
env:
# FIXME there must be two or more targets, or we'll get error on `@OptionalExpectation`
# > Declaration annotated with '@OptionalExpectation' can only be used in common module sources
- gradleArgs: --scan "-Dmirai.target=jvm;${{ matrix.targetName }};~others" "-Pkotlin.compiler.execution.strategy=in-process" "-Dorg.gradle.jvmargs=-Xmx4096m" "-Dfile.encoding=UTF-8"
+ gradleArgs: --scan
isMac: ${{ startsWith(matrix.os, 'macos') }}
isWindows: ${{ startsWith(matrix.os, 'windows') }}
isUbuntu: ${{ startsWith(matrix.os, 'ubuntu') }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index e870aef6f..9cb2d4922 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -102,16 +102,6 @@ jobs:
# Prepare environment for linking for macOS
- - if: ${{ env.isMac == 'true' }}
- name: Install OpenSSL
- run: >
- git clone https://github.com/openssl/openssl.git --recursive &&
- cd openssl &&
- git checkout tags/openssl-3.0.3 &&
- ./Configure --prefix=/opt/openssl --openssldir=/usr/local/ssl &&
- make &&
- sudo make install
-
- name: Clean and download dependencies
run: ./gradlew clean ${{ env.gradleArgs }}
@@ -155,164 +145,6 @@ jobs:
-Dgradle.publish.secret=${{ secrets.GRADLE_PUBLISH_SECRET }} -Pgradle.publish.secret=${{ secrets.GRADLE_PUBLISH_SECRET }}
continue-on-error: true
- publish-core-native:
- name: "Native (${{ matrix.os }})"
- needs: [ publish-others ] # Allow MPP metadata to be uploaded first.
- runs-on: ${{ matrix.os }}
- strategy:
- fail-fast: false
- matrix:
- os:
- - windows-2022
- - ubuntu-20.04
- # - macos-12 # macOS artifacts published in 'publish-others'
- include:
- - os: windows-2022
- targetName: mingwX64
- # parallelCompilation: false
- - os: ubuntu-20.04
- targetName: linuxX64
- # parallelCompilation: false
- - os: macos-12
- targetName: macosX64
- # parallelCompilation: true # macOS machine has 14G
- env:
- # FIXME there must be two or more targets, or we'll get error on `@OptionalExpectation`
- # > Declaration annotated with '@OptionalExpectation' can only be used in common module sources
- gradleArgs: --scan "-Dmirai.target=jvm;${{ matrix.targetName }};~other" "-Pkotlin.compiler.execution.strategy=in-process" "-Dorg.gradle.jvmargs=-Xmx4096m" "-Dfile.encoding=UTF-8"
- isMac: ${{ startsWith(matrix.os, 'macos') }}
- isWindows: ${{ startsWith(matrix.os, 'windows') }}
- isUbuntu: ${{ startsWith(matrix.os, 'ubuntu') }}
- isUnix: ${{ startsWith(matrix.os, 'macos') || startsWith(matrix.os, 'ubuntu') }}
- VCPKG_DEFAULT_BINARY_CACHE: ${{ startsWith(matrix.os, 'windows') && 'C:\vcpkg\binary_cache' || '/usr/local/share/vcpkg/binary_cache' }}
- steps:
- - uses: actions/checkout@v3
- with:
- submodules: 'recursive'
-
- - uses: actions/setup-java@v3
- with:
- distribution: 'adopt-openj9'
- java-version: '17'
-
- - name: Keys setup
- shell: bash
- run: |
- mkdir build-gpg-sign
- echo "$GPG_PRIVATE" > build-gpg-sign/keys.gpg
- echo "$GPG_PUBLIC_" > build-gpg-sign/keys.gpg.pub
- env:
- GPG_PRIVATE: ${{ secrets.GPG_PRIVATE_KEY }}
- GPG_PUBLIC_: ${{ secrets.GPG_PUBLIC_KEY }}
-
- - name: Setup Gradle
- uses: gradle/gradle-build-action@v2
-
- - name: Cache konan
- uses: pat-s/always-upload-cache@v3.0.11
- with:
- path: ~/.konan
- key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
- restore-keys: |
- ${{ runner.os }}-gradle-
-
- - name: Prepare to cache vcpkg
- if: ${{ env.isWindows == 'true' }}
- run: mkdir -p ${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
-
- - name: Cache vcpkg
- if: ${{ env.isWindows == 'true' }}
- uses: pat-s/always-upload-cache@v3.0.11
- with:
- path: ${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
- key: ${{ runner.os }}-vcpkg-binary-cache-${{ github.job }}
- restore-keys: |
- ${{ runner.os }}-vcpkg-binary-cache-
-
- - if: ${{ env.isUnix == 'true' }}
- run: chmod -R 777 *
-
- # Prepare environment for linking on macOS
- - if: ${{ env.isMac == 'true' }}
- name: Install OpenSSL on Mac OS
- run: >
- git clone https://github.com/openssl/openssl.git --recursive &&
- cd openssl &&
- git checkout tags/openssl-3.0.3 &&
- ./Configure --prefix=/opt/openssl --openssldir=/usr/local/ssl &&
- make &&
- sudo make install
-
- # Prepare environment for linking on Ubuntu
- - if: ${{ env.isUbuntu == 'true' }}
- name: Install OpenSSL on Ubuntu
- run: sudo apt install libssl-dev -y
-
- # Prepare environment for linking on Windows
- - if: ${{ env.isWindows == 'true' }}
- name: Setup Memory Environment on Windows
- run: >
- wmic pagefileset where name="D:\\pagefile.sys" set InitialSize=1024,MaximumSize=9216 &
- net stop mongodb
- shell: cmd
- continue-on-error: true
-
- - if: ${{ env.isWindows == 'true' }}
- name: Install OpenSSL & cURL on Windows
- run: |
- echo "set(VCPKG_BUILD_TYPE release)" | Out-File -FilePath "$env:VCPKG_INSTALLATION_ROOT\triplets\x64-windows.cmake" -Encoding utf8 -Append
- vcpkg install openssl:x64-windows curl[core,ssl]:x64-windows
- New-Item -Path $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\crypto.lib -ItemType SymbolicLink -Value $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\libcrypto.lib
- New-Item -Path $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\ssl.lib -ItemType SymbolicLink -Value $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\libssl.lib
- New-Item -Path $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\curl.lib -ItemType SymbolicLink -Value $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\libcurl.lib
- echo "$env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
-
- - name: Clean and download dependencies
- run: ./gradlew clean ${{ env.gradleArgs }}
-
- - name: "Test mirai-core-utils for ${{ matrix.os }}"
- run: ./gradlew :mirai-core-utils:${{ matrix.targetName }}Test ${{ env.gradleArgs }}
-
- - name: "Test mirai-core-api for ${{ matrix.os }}"
- run: ./gradlew :mirai-core-api:${{ matrix.targetName }}Test ${{ env.gradleArgs }}
-
- - name: "Test mirai-core for ${{ matrix.os }}"
- run: ./gradlew :mirai-core:${{ matrix.targetName }}Test ${{ env.gradleArgs }}
-
- - name: Initialize Publishing Caching Repository
- run: ./gradlew runcihelper --args sync-maven-metadata ${{ env.gradleArgs }}
-
- - name: Release RAM
- run: node ci-release-helper/scripts/kill-java.js
-
- # # Parallel compilation will exhaust machine memory causing OOM
- # - name: Assemble
- # run: ./gradlew assemble ${{ env.gradleArgs }} "-Porg.gradle.parallel=${{ matrix.parallelCompilation }}"
-
- - name: Publish MingwX64
- if: ${{ env.isWindows == 'true' }}
- run: ./gradlew publishMingwX64PublicationToMiraiStageRepoRepository ${{ env.gradleArgs }}
-
- - name: Publish LinuxX64
- if: ${{ env.isUbuntu == 'true' }}
- run: ./gradlew publishLinuxX64PublicationToMiraiStageRepoRepository ${{ env.gradleArgs }}
-
- - name: Publish macOSX64
- if: ${{ env.isMac == 'true' }}
- run: ./gradlew publishMacosX64PublicationToMiraiStageRepoRepository ${{ env.gradleArgs }}
-
- - name: Restore staging repository id
- uses: actions/download-artifact@v3
- with:
- name: publish-stage-id
- path: ci-release-helper/repoid
-
- - name: Release RAM
- run: node ci-release-helper/scripts/kill-java.js
-
- - name: Publish to maven central
- run: ./gradlew runcihelper --args publish-to-maven-central --scan "-Pcihelper.cert.username=${{ secrets.SONATYPE_USER }}" "-Pcihelper.cert.password=${{ secrets.SONATYPE_KEY }}"
-
#
# close-repository:
# runs-on: macos-12
diff --git a/.run/Build mirai-core for Host Native.run.xml b/.run/Build mirai-core for Host Native.run.xml
deleted file mode 100644
index be73589ce..000000000
--- a/.run/Build mirai-core for Host Native.run.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
- true
- false
-
-
-
\ No newline at end of file
diff --git a/.run/Build mirai-core libraries for host Native.run.xml b/.run/Build mirai-core libraries for host Native.run.xml
deleted file mode 100644
index ea9b32310..000000000
--- a/.run/Build mirai-core libraries for host Native.run.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
- true
- false
-
-
-
\ No newline at end of file
diff --git a/.run/Run Native Main host.run.xml b/.run/Run Native Main host.run.xml
deleted file mode 100644
index bbeaadaa4..000000000
--- a/.run/Run Native Main host.run.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- false
- true
- false
-
-
-
\ No newline at end of file
diff --git a/.run/Run Native Main linuxX64.run.xml b/.run/Run Native Main linuxX64.run.xml
deleted file mode 100644
index 93e990033..000000000
--- a/.run/Run Native Main linuxX64.run.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- false
- true
- false
-
-
-
\ No newline at end of file
diff --git a/.run/Run Native Main macosArm64.run.xml b/.run/Run Native Main macosArm64.run.xml
deleted file mode 100644
index 73617a26c..000000000
--- a/.run/Run Native Main macosArm64.run.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- false
- true
- false
-
-
-
\ No newline at end of file
diff --git a/.run/Run Native Main macosX64.run.xml b/.run/Run Native Main macosX64.run.xml
deleted file mode 100644
index 4a79bce41..000000000
--- a/.run/Run Native Main macosX64.run.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- false
- true
- false
-
-
-
\ No newline at end of file
diff --git a/.run/Run Native Main mingwX64.run.xml b/.run/Run Native Main mingwX64.run.xml
deleted file mode 100644
index b9fe9a782..000000000
--- a/.run/Run Native Main mingwX64.run.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- false
- true
- false
-
-
-
\ No newline at end of file
diff --git a/.run/Test mirai-core for host Native.run.xml b/.run/Test mirai-core for host Native.run.xml
deleted file mode 100644
index c45827201..000000000
--- a/.run/Test mirai-core for host Native.run.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
- true
- false
-
-
-
\ No newline at end of file
diff --git a/.run/Test mirai-core-api for host Native.run.xml b/.run/Test mirai-core-api for host Native.run.xml
deleted file mode 100644
index 1474c30f9..000000000
--- a/.run/Test mirai-core-api for host Native.run.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
- true
- false
-
-
-
\ No newline at end of file
diff --git a/.run/Test mirai-core-utils for host Native.run.xml b/.run/Test mirai-core-utils for host Native.run.xml
deleted file mode 100644
index b2f2ba885..000000000
--- a/.run/Test mirai-core-utils for host Native.run.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
- true
- false
-
-
-
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/HmppConfigure.kt b/buildSrc/src/main/kotlin/HmppConfigure.kt
index b15fe8a6e..02b9906af 100644
--- a/buildSrc/src/main/kotlin/HmppConfigure.kt
+++ b/buildSrc/src/main/kotlin/HmppConfigure.kt
@@ -10,21 +10,10 @@
import com.google.gradle.osdetector.OsDetector
import org.gradle.api.Project
import org.gradle.api.attributes.Attribute
-import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.getting
import org.gradle.kotlin.dsl.provideDelegate
-import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
-import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
-import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.TEST_COMPILATION_NAME
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
-import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
-import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
-import org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset
-import org.jetbrains.kotlin.gradle.plugin.mpp.*
-import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink
-import java.io.File
-import java.util.*
val MIRAI_PLATFORM_ATTRIBUTE: Attribute = Attribute.of(
"net.mamoe.mirai.platform", String::class.java
@@ -78,10 +67,6 @@ val HOST_KIND by lazy {
}
}
-enum class HostArch {
- X86, X64, ARM32, ARM64
-}
-
/// eg. "!a;!b" means to enable all targets but a or b
/// eg. "a;b;!other" means to disable all targets but a or b
val ENABLED_TARGETS by projectLazy {
@@ -98,16 +83,11 @@ fun getMiraiTargetFromGradle() =
?: "others"
fun isTargetEnabled(name: String): Boolean {
- val isNative = name in POSSIBLE_NATIVE_TARGETS
return when {
name in ENABLED_TARGETS -> true // explicitly enabled
"!$name" in ENABLED_TARGETS -> false // explicitly disabled
"~$name" in ENABLED_TARGETS -> false // explicitly disabled
- "native" in ENABLED_TARGETS && isNative -> true // native targets explicitly enabled
- "!native" in ENABLED_TARGETS && isNative -> false // native targets explicitly disabled
- "~native" in ENABLED_TARGETS && isNative -> false // native targets explicitly disabled
-
"!other" in ENABLED_TARGETS -> false // others disabled
"~other" in ENABLED_TARGETS -> false // others disabled
"!others" in ENABLED_TARGETS -> false // others disabled
@@ -119,41 +99,6 @@ fun isTargetEnabled(name: String): Boolean {
fun Set.filterTargets() =
this.filter { isTargetEnabled(it) }.toSet()
-val MAC_TARGETS: Set by projectLazy {
- setOf(
-// "watchosX86",
- "macosX64",
- "macosArm64",
-
- // Failed to generate cinterop for :mirai-core:cinteropOpenSSLIosX64: Process 'command '/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1
- // Exception in thread "main" java.lang.Error: /var/folders/kw/ndw272ns06s7cys2mcwwlb5c0000gn/T/1181140105365175708.c:1:10: fatal error: 'openssl/ec.h' file not found
- //
- // Note: the openssl/ec.h is actually there, seems Kotlin doesn't support that
-
-// "iosX64",
-// "iosArm64",
-// "iosArm32",
-// "iosSimulatorArm64",
-// "watchosX64",
-// "watchosArm32",
-// "watchosArm64",
-// "watchosSimulatorArm64",
-// "tvosX64",
-// "tvosArm64",
-// "tvosSimulatorArm64",
- ).filterTargets()
-}
-
-val WIN_TARGETS by projectLazy { setOf("mingwX64").filterTargets() }
-
-val LINUX_TARGETS by projectLazy { setOf("linuxX64").filterTargets() }
-
-val UNIX_LIKE_TARGETS by projectLazy { LINUX_TARGETS + MAC_TARGETS }
-
-val NATIVE_TARGETS by projectLazy { UNIX_LIKE_TARGETS + WIN_TARGETS }
-
-private val POSSIBLE_NATIVE_TARGETS by lazy { setOf("mingwX64", "macosX64", "macosArm64", "linuxX64") }
-
const val JVM_TOOLCHAIN_VERSION = 8
val JVM_TOOLCHAIN_ENABLED by projectLazy {
@@ -165,8 +110,6 @@ val JVM_TOOLCHAIN_ENABLED by projectLazy {
*
* 如果[启用 Android Instrumented Test][ENABLE_ANDROID_INSTRUMENTED_TESTS], 将会配置使用 Android SDK 配置真 Android target,
* `androidMain` 将能访问 Android SDK, 也能获得针对 Android 的 IDE 错误检查.
- *
- * @see configureNativeTargetsHierarchical
*/
fun Project.configureJvmTargetsHierarchical(androidNamespace: String) {
extensions.getByType(KotlinMultiplatformExtension::class.java).apply {
@@ -220,401 +163,6 @@ fun Project.configureJvmTargetsHierarchical(androidNamespace: String) {
}
}
-
-/**
- * Target 结构:
- * ```
- * common
- * |
- * /---------------+---------------\
- * jvmBase native
- * / \ / \
- * jvm android unix \
- * / \ mingwX64
- * / \
- * darwin linuxX64
- * |
- * *
- *
- * ```
- *
- * ``: macosX64, macosArm64
- *
- * @see configureJvmTargetsHierarchical
- */
-fun KotlinMultiplatformExtension.configureNativeTargetsHierarchical(
- project: Project
-) {
- if (NATIVE_TARGETS.isEmpty()) return
-
- val nativeMainSets = mutableListOf()
- val nativeTestSets = mutableListOf()
- val nativeTargets =
- mutableListOf() // actually KotlinNativeTarget, but KotlinNativeTarget is an internal API (complained by IDEA)
-
-
- fun KotlinMultiplatformExtension.addNativeTarget(
- preset: KotlinTargetPreset<*>,
- ): KotlinTarget {
- val target = targetFromPreset(preset, preset.name)
- nativeMainSets.add(target.compilations[MAIN_COMPILATION_NAME].kotlinSourceSets.first())
- nativeTestSets.add(target.compilations[TEST_COMPILATION_NAME].kotlinSourceSets.first())
- nativeTargets.add(target)
- return target
- }
-
-
- // project.configureNativeInterop("main", project.projectDir.resolve("src/nativeMainInterop"), nativeTargets)
- // project.configureNativeInterop("test", project.projectDir.resolve("src/nativeTestInterop"), nativeTargets)
-
-
- val sourceSets = project.objects.domainObjectContainer(KotlinSourceSet::class.java)
- .apply { addAll(project.kotlinSourceSets.orEmpty()) }
-
- val commonMain by sourceSets.getting
- val commonTest by sourceSets.getting
-
- val nativeMain by lazy {
- this.sourceSets.maybeCreate("nativeMain").apply {
- dependsOn(commonMain)
- }
- }
- val nativeTest by lazy {
- this.sourceSets.maybeCreate("nativeTest").apply {
- dependsOn(commonTest)
- }
- }
-
- if (UNIX_LIKE_TARGETS.isNotEmpty()) {
- val unixMain by lazy {
- this.sourceSets.maybeCreate("unixMain").apply {
- dependsOn(nativeMain)
- }
- }
- val unixTest by lazy {
- this.sourceSets.maybeCreate("unixTest").apply {
- dependsOn(nativeTest)
- }
- }
-
- val darwinMain by lazy {
- this.sourceSets.maybeCreate("darwinMain").apply {
- dependsOn(unixMain)
- }
- }
- val darwinTest by lazy {
- this.sourceSets.maybeCreate("darwinTest").apply {
- dependsOn(unixTest)
- }
- }
-
- presets.filter { it.name in MAC_TARGETS }.forEach { preset ->
- addNativeTarget(preset).run {
- compilations[MAIN_COMPILATION_NAME].kotlinSourceSets.forEach { it.dependsOn(darwinMain) }
- compilations[TEST_COMPILATION_NAME].kotlinSourceSets.forEach { it.dependsOn(darwinTest) }
- }
- }
-
- presets.filter { it.name in LINUX_TARGETS }.forEach { preset ->
- addNativeTarget(preset).run {
- compilations[MAIN_COMPILATION_NAME].kotlinSourceSets.forEach { it.dependsOn(unixMain) }
- compilations[TEST_COMPILATION_NAME].kotlinSourceSets.forEach { it.dependsOn(unixTest) }
- }
- }
- }
-
- presets.filter { it.name in WIN_TARGETS }.forEach { preset ->
- addNativeTarget(preset).run {
- compilations[MAIN_COMPILATION_NAME].kotlinSourceSets.forEach { it.dependsOn(nativeMain) }
- compilations[TEST_COMPILATION_NAME].kotlinSourceSets.forEach { it.dependsOn(nativeTest) }
- }
- }
-
- // Workaround from https://youtrack.jetbrains.com/issue/KT-52433/KotlinNative-Unable-to-generate-framework-with-Kotlin-1621-and-Xcode-134#focus=Comments-27-6140143.0-0
- project.tasks.withType().configureEach {
- val properties = listOf(
- "ios_arm32", "watchos_arm32", "watchos_x86"
- ).joinToString(separator = ";") { "clangDebugFlags.$it=-Os" }
- kotlinOptions.freeCompilerArgs += listOf(
- "-Xoverride-konan-properties=$properties"
- )
- }
-
-// WIN_TARGETS.forEach { targetName ->
-// val target = targets.getByName(targetName) as KotlinNativeTarget
-// if (!IDEA_ACTIVE && HOST_KIND == HostKind.WINDOWS) {
-// // add release test to run on CI
-// project.afterEvaluate {
-// target.findOrCreateTest(NativeBuildType.RELEASE) {
-// // use linkReleaseTestMingwX64 for mingwX64Test to save memory
-// tasks.getByName("mingwX64Test", KotlinNativeTest::class)
-// .executable(linkTask) { linkTask.binary.outputFile }
-// }
-// }
-// }
-// }
-
- // Register platform tasks, e.g. linkDebugSharedHost
- project.afterEvaluate {
- val targetName = HOST_KIND.targetName
- val targetNameCapitalized = targetName.capitalize()
- project.tasks.run {
- listOf(
- "compileKotlin",
- "linkDebugTest",
- "linkReleaseTest",
- "linkDebugShared",
- "linkReleaseShared",
- "linkDebugStatic",
- "linkReleaseStatic",
- ).forEach { name ->
- findByName("$name$targetNameCapitalized")?.let { plat ->
- register("${name}Host") {
- group = "mirai"
- description = "Run ${plat.name} which can be run on the current Host."
- dependsOn(plat)
- }
- }
- }
-
- findByName("${targetName}Test")?.let { plat ->
- register("hostTest") {
- group = "mirai"
- description = "Run ${plat.name} which can be run on the current Host."
- dependsOn(plat)
- }
- }
- }
- project.disableCrossCompile() // improve speed
- }
-}
-
-fun KotlinMultiplatformExtension.configureNativeTargetBinaries(project: Project) {
- if (!System.getProperty("mirai.native.binaries", "false").toBoolean()) {
- // Must enable KotlinNativeLink by argument "mirai.native.link".
-
- // :mirai-core:linkReleaseSharedMacosX64
- return
-// disableNativeLinkTasks(project)
- }
-
- NATIVE_TARGETS.forEach { targetName ->
- val target = targets.getByName(targetName) as KotlinNativeTarget
- target.binaries {
- sharedLib(listOf(NativeBuildType.DEBUG, NativeBuildType.RELEASE)) {
- baseName = project.name.lowercase(Locale.ROOT).replace("-", "")
- }
- staticLib(listOf(NativeBuildType.DEBUG, NativeBuildType.RELEASE)) {
- baseName = project.name.lowercase(Locale.ROOT).replace("-", "")
- }
- }
- }
-}
-
-private fun disableNativeLinkTasks(project: Project) {
- project.tasks.withType()
- .filter { it.binary.outputKind != NativeOutputKind.TEST }
- .forEach {
- it.enabled = false
- project.logger.warn("Disabling KotlinNativeLink: ${it.path}")
- }
-}
-
-private fun KotlinNativeTarget.findOrCreateTest(buildType: NativeBuildType, configure: TestExecutable.() -> Unit) =
- binaries.findTest(buildType)?.apply(configure) ?: binaries.test(listOf(buildType), configure)
-
-
-// e.g. Linker will try to link curl for mingwX64 but this can't be done on macOS.
-fun Project.disableCrossCompile() {
- project.afterEvaluate {
- if (HOST_KIND != HostKind.MACOS_ARM64) {
- disableTargetLink(this, HostKind.MACOS_ARM64.targetName)
- }
- if (HOST_KIND != HostKind.MACOS_X64) {
- disableTargetLink(this, HostKind.MACOS_X64.targetName)
- }
- if (HOST_KIND != HostKind.WINDOWS) {
- WIN_TARGETS.forEach { target -> disableTargetLink(this, target) }
- }
- if (HOST_KIND != HostKind.LINUX) {
- LINUX_TARGETS.forEach { target -> disableTargetLink(this, target) }
- }
- }
-}
-
-private fun disableTargetLink(project: Project, target: String) {
- // Don't disable compileKotlin tasks. These tasks ensure code syntax is correct.
- project.tasks.findByName("linkDebugTest${target.titlecase()}")?.enabled = false
- project.tasks.findByName("linkReleaseTest${target.titlecase()}")?.enabled = false
- project.tasks.findByName("linkDebugShared${target.titlecase()}")?.enabled = false
- project.tasks.findByName("linkReleaseShared${target.titlecase()}")?.enabled = false
- project.tasks.findByName("linkDebugStatic${target.titlecase()}")?.enabled = false
- project.tasks.findByName("linkReleaseStatic${target.titlecase()}")?.enabled = false
- project.tasks.findByName("${target}Test")?.enabled = false
-}
-
-private fun Project.linkerDirs(): List {
- return listOf(
- ":mirai-core",
- ":mirai-core-api",
- ":mirai-core-utils",
- ).map {
- rootProject.project(it).projectDir.resolve("src/nativeMainInterop/target/debug/").absolutePath
- }
-}
-
-private fun Project.includeDirs(): List {
- return listOf(
- ":mirai-core",
- ":mirai-core-api",
- ":mirai-core-utils",
- ).map {
- rootProject.project(it).projectDir.resolve("src/nativeMainInterop/").absolutePath
- }
-}
-
-private fun Project.configureNativeInterop(
- compilationName: String, nativeInteropDir: File, nativeTargets: MutableList
-) {
- val crateName = project.name.replace("-", "_") + "_i"
-
- if (nativeInteropDir.exists() && nativeInteropDir.isDirectory && nativeInteropDir.resolve("build.rs").exists()) {
- val kotlinDylibName = project.name.replace("-", "_") + "_i"
-
- val headerName = "$crateName.h"
- val rustLibDir = nativeInteropDir.resolve("target/debug/")
-
- var interopTaskName = ""
-
- configure(nativeTargets) {
- interopTaskName = compilations.getByName(compilationName).cinterops.create(compilationName) {
- defFile(nativeInteropDir.resolve("interop.def"))
- val headerFile = nativeInteropDir.resolve(headerName)
- if (headerFile.exists()) headers(headerFile)
- }.interopProcessingTaskName
-
- binaries {
- sharedLib {
- linkerOpts("-v")
- linkerOpts("-L${rustLibDir.absolutePath.replace("\\", "/")}")
-// linkerOpts("-lmirai_core_utils_i")
- linkerOpts("-undefined", "dynamic_lookup")
- baseName = project.name
- }
- getTest(NativeBuildType.DEBUG).apply {
- linkerOpts("-v")
- linkerOpts("-L${rustLibDir.absolutePath.replace("\\", "/")}")
- linkerOpts("-lmirai_core_utils_i")
-// linkerOpts("-undefined", "dynamic_lookup")
- }
- }
- }
-
- val cbindgen = tasks.register("cbindgen${compilationName.titlecase()}") {
- group = "mirai"
- description = "Generate C Headers from Rust"
- inputs.files(project.objects.fileTree().from(nativeInteropDir.resolve("src"))
- .filterNot { it.name == "bindings.rs" })
- outputs.file(nativeInteropDir.resolve(headerName))
- doLast {
- exec {
- workingDir(nativeInteropDir)
- commandLine(
- "cbindgen", "--config", "cbindgen.toml", "--crate", crateName, "--output", headerName
- )
- }
- }
- }
-
- val generateRustBindings = tasks.register("generateRustBindings${compilationName.titlecase()}") {
- group = "mirai"
- description = "Generates Rust bindings for Kotlin"
- dependsOn(cbindgen)
- }
-
- afterEvaluate {
- val cinteropTask = tasks.getByName(interopTaskName)
- cinteropTask.mustRunAfter(cbindgen)
- generateRustBindings.get().dependsOn(cinteropTask)
- }
-
- val bindgen = tasks.register("bindgen${compilationName.titlecase()}") {
- group = "mirai"
- val bindingsPath = nativeInteropDir.resolve("src/bindings.rs")
- val headerFile = buildDir.resolve("bin/native/debugShared/lib${kotlinDylibName}_api.h")
- inputs.files(headerFile)
- outputs.file(bindingsPath)
- mustRunAfter(tasks.findByName("linkDebugSharedNative"))
- doLast {
- exec {
- workingDir(nativeInteropDir)
- // bindgen input.h -o bindings.rs
- commandLine(
- "bindgen",
- headerFile,
- "-o", bindingsPath,
- )
- }
- }
- }
-
- tasks.register("generateKotlinBindings${compilationName.titlecase()}") {
- group = "mirai"
- description = "Generates Kotlin bindings for Rust"
- dependsOn(bindgen)
- dependsOn(tasks.findByName("linkDebugSharedNative"))
- }
-
- var targetCompilation: KotlinNativeCompilation? = null
- configure(nativeTargets) {
- val compilations = compilations.filter { nativeInteropDir.name.contains(it.name, ignoreCase = true) }
- check(compilations.isNotEmpty()) { "Should be at lease one corresponding native compilation, but found 0" }
- targetCompilation = compilations.single()
-// targetCompilation!!.compileKotlinTask.dependsOn(cbindgen)
-// tasks.getByName("cinteropNative$name").dependsOn(cbindgen)
- }
-
- if (targetCompilation != null) {
- val compileRust = tasks.register("compileRust${compilationName.titlecase()}") {
- group = "mirai"
- inputs.files(nativeInteropDir.resolve("src"))
- outputs.file(rustLibDir.resolve("lib$crateName.dylib"))
-// dependsOn(targetCompilation!!.compileKotlinTask)
- dependsOn(bindgen)
- dependsOn(tasks.findByName("linkDebugSharedNative")) // dylib to link
- doLast {
- exec {
- workingDir(nativeInteropDir)
- commandLine(
- "cargo",
- "build",
- "--color", "always",
- "--all",
-// "--", "--color", "always", "2>&1"
- )
- }
- }
- }
-
- tasks.getByName("assemble").dependsOn(compileRust)
- }
- }
-}
-
-private fun Project.configureNativeLinkOptions(nativeTargets: MutableList) {
- configure(nativeTargets) {
- binaries {
- for (buildType in NativeBuildType.values()) {
- findTest(buildType)?.apply {
- linkerOpts("-v")
- linkerOpts(*linkerDirs().map { "-L$it" }.toTypedArray())
- linkerOpts("-undefined", "dynamic_lookup") // resolve symbol in runtime
- }
- }
- }
- }
-}
-
fun String.titlecase(): String {
if (this.isEmpty()) return this
val c = get(0)
diff --git a/docs/ConfiguringMultiplatformProjects.md b/docs/ConfiguringMultiplatformProjects.md
index 2c607b730..69b6e9d19 100644
--- a/docs/ConfiguringMultiplatformProjects.md
+++ b/docs/ConfiguringMultiplatformProjects.md
@@ -11,16 +11,12 @@
mirai 上传到 Maven Central 的预编译模块列表如下表所示。在表中列举的平台即为你的项目可以使用的平台。
如果你使用了一个不受支持的平台,在构建项目时将会得到来自 Gradle 的依赖解决错误。
-mirai 实际上能支持 arm 架构,但由于 GitHub Actions 均为 x86 主机,而现阶段配置 Kotlin 交叉编译也较困难,就没有支持。
-没有支持其他小众平台是因为实用性有限。若有需求欢迎 PR。
+mirai 曾在 2.13.0 ~ 2.15.0-RC(不包含)支持编译到 macOS、Window、Linux 平台。自 2.15.0-RC 已完全删除对这些平台的支持。
-| 发布平台名称 | 描述 |
-|------------|------------------|
-| jvm | JVM |
-| android | Android (Dalvik) |
-| mingwX64 | Windows x64 |
-| macosX64 | macOS x64 |
-| linuxX64 | Linux x64 |
+| 发布平台名称 | 描述 |
+|---------|------------------|
+| jvm | JVM |
+| android | Android (Dalvik) |
## 添加依赖
@@ -49,7 +45,7 @@ kotlin {
## 解决问题
-如果你在使用多平台项目时遇到问题,那应该是正常的。Kotlin 多平台项目在 1.7 仍然是一个测试版功能。mirai 的 native 平台支持是在 2.13.0 才提供。欢迎在 issues 提交多平台相关问题。
+如果你在使用多平台项目时遇到问题,那应该是正常的。Kotlin 多平台项目在 1.7 仍然是一个测试版功能。欢迎在 issues 提交多平台相关问题。
> 依赖配置完成,
> - [回到 Mirai 文档索引](README.md#使用-mirai)
\ No newline at end of file
diff --git a/docs/contributing/README.md b/docs/contributing/README.md
index e0bbc6314..2877c9af5 100644
--- a/docs/contributing/README.md
+++ b/docs/contributing/README.md
@@ -105,40 +105,26 @@ core'
[HMPP]: https://kotlinlang.org/docs/multiplatform-discover-project.html
-core 三个模块都使用 Kotlin [HMPP] 功能,同时支持 JVM 和 Native
+core 三个模块都使用 Kotlin [HMPP] 功能,同时支持 JVM 和 Android
两种平台。你可以在 [Kotlin 官方文档][HMPP] 了解 HMPP 模式。
core 的编译目标层级结构如图所示:
```
- common
- |
- /---------------+---------------\
- jvmBase native
- / \ / \
- jvm android unix \
- / \ mingwX64
- / \
- darwin linuxX64
- |
- *
-
+ common
+ / \
+ jvm android
```
-| 发布平台名称 | 描述 |
-|------------|------------------|
-| jvm | JVM |
-| android | Android (Dalvik) |
-| mingwX64 | Windows x64 |
-| macosX64 | macOS x64 |
-| macosArm64 | macOS arm64 |
-| linuxX64 | Linux x64 |
+| 发布平台名称 | 描述 |
+|---------|------------------|
+| jvm | JVM |
+| android | Android (Dalvik) |
备注:
- common 包含全平台通用代码,绝大部分代码都位于 common;
- jvmBase 包含针对 JVM 平台的通用代码;
-- `` 为 macOS,iOS,WatchOS 等 Apple 平台目标。
## 开发提示
@@ -175,32 +161,24 @@ mirai.enable.jvmtoolchain.special=false
所有目标默认都启用。
-**注意**,在关闭一个目标后,将无法编辑该目标的相关源集的源码。关闭部分 native 目标后也可能会影响 native 目标平台原生接口的数据类型。
-因此若非主机性能太差或在 CI 机器运行,**不建议**关闭 native 目标。
+**注意**,在关闭一个目标后,将无法编辑该目标的相关源集的源码。
+因此若非主机性能太差或在 CI 机器运行,**不建议**关闭目标。
[//]: # (备注: 如果要发版, 必须开启全部目标, 否则会导致 metadata 中的平台不全)
- `xxx`:显式启用 `xxx` 目标
- `!xxx`:显式禁用 `xxx` 目标
-- `native`:显式启用所有 native 目标
-- `!native`:禁用没有显式启用的所有 native 目标
- `others`:显式启用其他所有所有目标
- `!others`:禁用没有显式启用的所有目标
-其中 xxx 表示构建目标名称。可用的目标名称有(区分大小写):`jvm`、`android`、`macosX64`、`macosArm64`、`mingwX64`、`linuxX64`
+其中 xxx 表示构建目标名称。可用的目标名称有(区分大小写):`jvm`、`android`
```
-# 禁用所有 native 目标,启用其他目标(启用 jvm 和 android)
-projects.mirai-core.targets=!native;others
-
-# 启用 `jvm` 和 `android` 目标,禁用其他所有目标(禁用所有 native 目标)
-projects.mirai-core.targets=jvm;android;!others
-
-# 只启用 `jvm` 目标,禁用其他所有目标
+# 只启用 `jvm` 目标,禁用其他所有目标 (Android)
projects.mirai-core.targets=jvm;!others
-# 指定启用 `jvm` 和 `macosX64` 目标,禁用其他所有目标
-projects.mirai-core.targets=jvm;macosX64;!others
+# 启用 `jvm` 和 `android` 目标
+projects.mirai-core.targets=jvm;android
```
### 直接启动 mirai-core 本地测试
@@ -209,9 +187,7 @@ projects.mirai-core.targets=jvm;macosX64;!others
在 JVM 平台直接启动 mirai-core, 见 [mirai-core/jvmTest](/mirai-core/src/jvmTest/README.md)
-在 native 平台直接启动 mirai-core, 见 [mirai-core/nativeTest](/mirai-core/src/nativeTest/kotlin/local/README.md)
-
-## 构建 mirai 项目 JAR 以及动态链接库
+## 构建 mirai 项目 JAR
查看 [Building](building/README.md)
diff --git a/docs/contributing/SimpleInstructions.md b/docs/contributing/SimpleInstructions.md
index aacb49bee..dde2173b5 100644
--- a/docs/contributing/SimpleInstructions.md
+++ b/docs/contributing/SimpleInstructions.md
@@ -29,5 +29,3 @@
./gradlew publishMiraiArtifactsToMavenLocal "-Dprojects.mirai-core.targets=jvm;android;!others"
```
若上述命令不工作,尝试在 Android Studio 中打开项目并在 Studio 的终端中执行命令。
-- 我是 mirai native 用户,我需要 `.dll/.so/.dylib`:
- 你不能简单地构建这些动态链接库,因为它们需要依赖。阅读 [BuildingCoreNative](building/BuildingCoreNative.md)。
diff --git a/docs/contributing/building/BuildingCoreNative.md b/docs/contributing/building/BuildingCoreNative.md
deleted file mode 100644
index 5d56144d2..000000000
--- a/docs/contributing/building/BuildingCoreNative.md
+++ /dev/null
@@ -1,194 +0,0 @@
-[OpenSSL.def]: ../../mirai-core/src/nativeMain/cinterop/OpenSSL.def
-
-Kotlin 会自动配置 Native 编译器,要构建 Mirai 的 Native 目标还需要准备相关依赖。
-
-### 操作系统条件
-
-主机操作系统为以下任一:
-
-- Windows x86_64 (amd64)
-- macOS x86_64 (amd64)
-- macOS aarch64 (arm64)
-- Linux x86_64 (amd64)
-
-注意:32 位操作系统不受支持。未列举的操作系统不受支持。
-
-目前 Kotlin 对交叉编译支持有限,只能在一个主机上编译该主机平台的目标。例如在 Windows x86_64 主机上只能编译
-Windows x86_64 目标;在 macOS aarch64 主机上只能编译 macOS aarch64 目标。
-
-与其他 Native 语言相同,Kotlin 的应用使用依赖时同样需要配置链接,mirai
-已经配置了常用目录。也可以在 `mirai-core/src/nativeMain/cinterop/OpenSSL.def`
-修改 `linkerOpts` 即链接器参数,以增加自定义路径。
-
-### 性能提示
-
-在编译和链接时可能需要大量内存,请使用至少拥有 8GB 内存的主机。使用 32GB 内存的主机可以获得不错的体验。mirai
-默认启用多项目同时编译,编译时可能会使用大量主机资源。
-
-如果主机可用内存较低,请不要执行 `./gradlew assemble`
-编译全部项目,这可能会导致内存溢出,也将会导致编译缓慢。可以单独为某个模块执行批量编译,如 `./gradlew :mirai-console:assemble`
-。
-
-#### 编译耗时
-
-若使用 Apple M1 Max 或同等级 CPU (AMD R7 5800X / Intel i7-12700K / Intel
-i9-12950HX),单独执行 `./gradlew assemble` 编译并连接全部项目 (含动态链接库和静态链接库) 需时约 9
-分钟。单独执行 `./gradlew check` 需约 4 分钟。
-但在 GitHub 的 2 核心 CPU Actions 机器上执行 `assemble` 通常需要约 40 分钟,。
-
-### 安装 OpenSSL
-
-所有上述主机都需要进行这一步。
-
-可以访问 OpenSSL 官网 `https://curl.se/download.html` 安装。
-
-#### 在 Ubuntu 通过 Aptitude 安装 OpenSSL
-
-```shell
-$ sudo apt install libssl-dev # 安装 OpenSSL
-$ sudo apt install gcc-multilib # 若遇到链接问题可额外尝试此命令
-```
-
-#### 在 macOS 通过 Homebrew 安装 OpenSSL
-
-```shell
-$ brew install openssl@3
-```
-
-注意:若遇到无法链接等问题,可以尝试通过源码编译安装。
-
-#### 在 macOS 或 Linux 通过源码编译安装 OpenSSL
-
-请参考 [OpenSSL 文档](https://github.com/openssl/openssl/blob/master/INSTALL.md#prerequisites)
-准备 OpenSSL 的要求。
-
-以下命令可能会帮助你(这是 mirai 的 GitHub Actions 使用的命令)。
-
-```shell
-$ git clone https://github.com/openssl/openssl.git --recursive
-$ cd openssl
-$ git checkout tags/openssl-3.0.3
-$ ./Configure --prefix=/opt/openssl --openssldir=/usr/local/ssl
-$ make
-$ sudo make install
-```
-
-若在 Ubuntu 遇到链接问题,可额外尝试此命令:
-
-```shell
-$ sudo apt install gcc-multilib
-```
-
-#### 在 Windows 通过 vcpkg 安装 OpenSSL
-
-你需要提前安装 [vcpkg](https://github.com/microsoft/vcpkg/blob/master/README_zh_CN.md)
-。
-
-以下命令可能会帮助你(这是 mirai 的 GitHub Actions 使用的命令)。
-
-```powershell
-echo "set(VCPKG_BUILD_TYPE release)" | Out-File -FilePath "$env:VCPKG_INSTALLATION_ROOT\triplets\x64-windows.cmake" -Encoding utf8 -Append
-vcpkg install openssl:x64-windows curl[core, ssl]: x64-windows
-New-Item -Path $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\crypto.lib -ItemType SymbolicLink -Value $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\libcrypto.lib
-New-Item -Path $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\ssl.lib -ItemType SymbolicLink -Value $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\libssl.lib
-New-Item -Path $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\curl.lib -ItemType SymbolicLink -Value $env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\lib\libcurl.lib
-echo "$env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
-```
-
-由于链接器只识别不包含 `lib` 前缀的文件(如 `ssl.lib` 而非 `libssl.lib`,vcpkg 编译产物为后者),上述 `New-Item` 创建一个无 `lib` 前缀的链接指向库文件。
-
-注意:
-
-- 你将需要修改链接器配置(位于 `mirai-core/src/nativeMain/cinterop/OpenSSL.def`
- ),增加 `linkerOpts` 和 `compilerOpts` 指向你本地安装的路径。
-- 不要将修改路径后的 `OpenSSL.def` 通过 Git 推送到 mirai 仓库或 PR。
-
-#### 在 Windows 通过源码编译安装 OpenSSL
-
-在 Windows,可通过源码编译安装,请使用 Command Prompt (cmd)。
-
-你需要提前安装 [Git](https://git-scm.com/)
-和 [Microsoft Visual Studio](https://visualstudio.microsoft.com/zh-hans/)
-,并修改以下命令中的路径。
-
-请参考 [OpenSSL 文档](https://github.com/openssl/openssl/blob/master/INSTALL.md#prerequisites)
-准备 OpenSSL 的要求。
-
-以下命令可能会帮助你(这是 mirai 的 GitHub Actions 使用过的命令)。
-
-```shell
-git clone https://github.com/openssl/openssl.git --recursive
-cd openssl
-git checkout tags/openssl-3.0.3
-perl Configure VC-WIN64A --prefix=C:/openssl --openssldir=C:/openssl/ssl no-asm
-"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64 && nmake && nmake install
-```
-
-注意:
-
-- `--prefix=C:/openssl --openssldir=C:/openssl/ssl` 表示将 OpenSSL
- 安装在 `C:/openssl`,mirai
- 已经配置会使用此路径寻找链接库。你也可以更换为其他路径,但就需要同步修改配置(位于 `mirai-core/src/nativeMain/cinterop/OpenSSL.def`
- );
-- 不要将修改路径后的 `OpenSSL.def` 通过 Git 推送到 mirai 仓库或 PR。
-
-### 安装 cURL
-
-mirai 在 Windows 上使用
-cURL,在其他平台使用 [Ktor CIO](https://ktor.io/docs/http-client-engines.html#cio)
-,因此只有 Windows 系统需要进行这一步。
-
-可以访问 cURL 官网 安装。
-
-提示:如果在[链接](#链接并测试)时遇到找不到 cURL
-相关符号的问题,请尝试修改链接器参数。尽管 `mirai-core/src/nativeMain/cinterop/OpenSSL.def`
-是用于 `OpenSSL.def` 的,也可以在这个文件配置 cURL 路径。
-
-### 编译
-
-在任意主机上可以执行所有目标的 Kotlin 编译,但不能执行链接。要执行特定目标的编译,运行 Gradle
-任务 `compileKotlinXXX`,其中 `XXX` 可以是:`MacosX64`、`MacosArm64`、`MingwX64`
-或 `LinuxX64`。
-
-也可以执行 `compileKotlinHost`,将自动根据当前主机选择合适的目标。
-
-### 链接并测试
-
-执行 core 模块的 `hostTest`,将根据主机选择合适的测试并运行。
-
-详情参考 [Kotlin 官方文档](https://kotlinlang.org/docs/multiplatform-run-tests.html)
-。
-
-### 链接并构建动态链接库
-
-注意,只有 mirai-core 可以构建可用的动态链接库。所有动态链接库和静态链接库的构建都是默认关闭的,需要使用 `-Dmirai.native.binaries=true` 才能启用。
-
-## 构建 core 的 Native 目标
-
-在提供 `-Dmirai.native.binaries=true` 参数的情况下,执行 `:mirai-core:linkDebugSharedHost`
-或 `:mirai-core:linkReleaseSharedHost`。Debug 版本会保留调试符号,能显示完整错误堆栈;而
-Release 拥有更小体积(比 Debug 减小 50%)。
-
-示例:
-
-```shell
-./gradlew :mirai-core:linkDebugSharedHost "-Dmirai.native.binaries=true"
-
-./gradlew :mirai-core:linkReleaseSharedMacoxX64 "-Dmirai.native.binaries=true"
-```
-
-这也会同时生成一个头文件(`.h`
-)供交互使用。详情查看 [Kotlin 官方文档](https://kotlinlang.org/docs/native-c-interop.html)
-。
-
-可以在 `mirai-core/build/bin/macosArm64/debugShared/` 类似路径找到生成的动态链接库和头文件。
-
-### 链接并构建静态链接库
-
-注意,只有 mirai-core 可以构建可用的静态链接库。
-
-与构建动态链接库类似,在提供 `-Dmirai.native.binaries=true` 参数的情况下,执行 `:mirai-core:linkDebugStaticHost`
-或 `:mirai-core:linkReleaseStaticHost`。Debug 版本会保留调试符号,能显示完整错误堆栈;而
-Release 拥有更小体积(比 Debug 减小 50%)。
-
-可以在 `mirai-core/build/bin/macosArm64/debugStatic/` 类似路径找到生成的静态链接库和头文件。
diff --git a/docs/contributing/building/README.md b/docs/contributing/building/README.md
index 4f02183ed..a355d6108 100644
--- a/docs/contributing/building/README.md
+++ b/docs/contributing/building/README.md
@@ -31,10 +31,6 @@ Gradle 任务:
查看 [BuildingCoreAndroid](BuildingCoreAndroid.md)。
-### 构建 core 的 Native 目标
-
-查看 [BuildingCoreNative](BuildingCoreNative.md)。
-
## 构建 IntelliJ 插件
可通过如下命令构建 IntelliJ 平台 IDE 的插件。构建成功的插件将可以在 `mirai-console/tools/intellij-plugin/build/distribution` 中找到。
diff --git a/gradle.properties b/gradle.properties
index 7ed88a5e9..62749b2ca 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -12,7 +12,6 @@ kotlin.incremental.multiplatform=true
org.gradle.jvmargs=-Xmx7000m -Dfile.encoding=UTF-8 --illegal-access=permit -Dkotlin.daemon.jvm.options=--illegal-access=permit --add-opens java.base/java.util=ALL-UNNAMED
org.gradle.parallel=true
org.gradle.vfs.watch=true
-kotlin.native.binary.memoryModel=experimental
#kotlin.mpp.enableCompatibilityMetadataVariant=true
systemProp.org.gradle.internal.publish.checksums.insecure=true
gnsp.disableApplyOnlyOnRootProjectEnforcement=true
@@ -20,7 +19,6 @@ mirai.android.target.api.level=21
# Enable if you want to use mavenLocal for both Gradle plugin and project dependencies resolutions.
systemProp.use.maven.local=false
org.gradle.caching=true
-kotlin.native.ignoreIncorrectDependencies=true
kotlin.mpp.enableCInteropCommonization=true
kotlin.mpp.stability.nowarn=true
kotlin.mpp.androidSourceSetLayoutVersion=2
diff --git a/mirai-console/tools/compiler-annotations/build.gradle.kts b/mirai-console/tools/compiler-annotations/build.gradle.kts
index 0b638ec30..eb8a288fa 100644
--- a/mirai-console/tools/compiler-annotations/build.gradle.kts
+++ b/mirai-console/tools/compiler-annotations/build.gradle.kts
@@ -22,7 +22,6 @@ kotlin {
apply(plugin = "explicit-api")
configureJvmTargetsHierarchical("net.mamoe.mirai.compiler.annotations")
- configureNativeTargetsHierarchical(project)
}
configureMppPublishing()
diff --git a/mirai-core-api/build.gradle.kts b/mirai-core-api/build.gradle.kts
index 6dfd27703..70fba6757 100644
--- a/mirai-core-api/build.gradle.kts
+++ b/mirai-core-api/build.gradle.kts
@@ -32,8 +32,6 @@ kotlin {
configureJvmTargetsHierarchical("net.mamoe.mirai")
- configureNativeTargetsHierarchical(project)
-
sourceSets {
val commonMain by getting {
dependencies {
@@ -87,11 +85,6 @@ kotlin {
runtimeOnly(files("build/classes/kotlin/jvm/test")) // classpath is not properly set by IDE
}
}
-
- findByName("nativeMain")?.apply {
- dependencies {
- }
- }
}
}
diff --git a/mirai-core-api/src/commonMain/kotlin/contact/announcement/OfflineAnnouncement.kt b/mirai-core-api/src/commonMain/kotlin/contact/announcement/OfflineAnnouncement.kt
index c1dff206f..8f5226cc7 100644
--- a/mirai-core-api/src/commonMain/kotlin/contact/announcement/OfflineAnnouncement.kt
+++ b/mirai-core-api/src/commonMain/kotlin/contact/announcement/OfflineAnnouncement.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
+ * Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -16,15 +16,10 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import net.mamoe.mirai.contact.announcement.OfflineAnnouncement.Companion.serializer
import net.mamoe.mirai.utils.cast
-import net.mamoe.mirai.utils.copy
import net.mamoe.mirai.utils.map
import net.mamoe.mirai.utils.safeCast
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
-import kotlin.jvm.JvmOverloads
-import kotlin.jvm.JvmStatic
-import kotlin.jvm.JvmSynthetic
-import kotlin.native.CName
/**
* 表示在本地构建的 [Announcement].
@@ -95,7 +90,6 @@ public sealed interface OfflineAnnouncement : Announcement {
* 依据 [from] 创建 [OfflineAnnouncement]. 若 [from] 类型为 [OfflineAnnouncement] 则直接返回 [from].
* @since 2.7
*/
-@CName("", "OfflineAnnouncement_new")
public inline fun OfflineAnnouncement(from: Announcement): OfflineAnnouncement =
OfflineAnnouncement.from(from)
@@ -105,7 +99,6 @@ public inline fun OfflineAnnouncement(from: Announcement): OfflineAnnouncement =
* @param parameters 可选的附加参数
* @since 2.7
*/
-@CName("", "OfflineAnnouncement_new2")
public inline fun OfflineAnnouncement(
content: String,
parameters: AnnouncementParameters = AnnouncementParameters.DEFAULT
@@ -118,7 +111,6 @@ public inline fun OfflineAnnouncement(
* @see AnnouncementParametersBuilder
* @since 2.7
*/
-@CName("", "OfflineAnnouncement_new3")
public inline fun OfflineAnnouncement(
content: String,
parameters: AnnouncementParametersBuilder.() -> Unit
diff --git a/mirai-core-api/src/commonMain/kotlin/message/data/At.kt b/mirai-core-api/src/commonMain/kotlin/message/data/At.kt
index a3ff0a887..3e97b67dc 100644
--- a/mirai-core-api/src/commonMain/kotlin/message/data/At.kt
+++ b/mirai-core-api/src/commonMain/kotlin/message/data/At.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
+ * Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -24,10 +24,6 @@ import net.mamoe.mirai.message.code.CodableMessage
import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiInternalApi
-import kotlin.jvm.JvmMultifileClass
-import kotlin.jvm.JvmName
-import kotlin.jvm.JvmSynthetic
-import kotlin.native.CName
/**
@@ -88,7 +84,6 @@ public data class At(
* @see Member.at
*/
@JvmSynthetic
-@CName("", "At_new")
public inline fun At(user: UserOrBot): At = At(user.id)
/**
diff --git a/mirai-core-api/src/commonMain/kotlin/message/data/Audio.kt b/mirai-core-api/src/commonMain/kotlin/message/data/Audio.kt
index 6a106dba3..c8a5fc381 100644
--- a/mirai-core-api/src/commonMain/kotlin/message/data/Audio.kt
+++ b/mirai-core-api/src/commonMain/kotlin/message/data/Audio.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
+ * Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -22,11 +22,6 @@ import net.mamoe.mirai.message.MessageSerializers
import net.mamoe.mirai.message.data.MessageChain.Companion.serializeToJsonString
import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.*
-import kotlin.jvm.JvmMultifileClass
-import kotlin.jvm.JvmName
-import kotlin.jvm.JvmStatic
-import kotlin.jvm.JvmSynthetic
-import kotlin.native.CName
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds
@@ -234,7 +229,6 @@ public interface OfflineAudio : Audio {
* @since 2.7
*/
@JvmSynthetic
-@CName("", "OfflineAudio_new")
public inline fun OfflineAudio(
filename: String,
fileMd5: ByteArray,
@@ -248,7 +242,6 @@ public inline fun OfflineAudio(
* @since 2.7
*/
@JvmSynthetic
-@CName("", "OfflineAudio_new2")
public inline fun OfflineAudio(
onlineAudio: OnlineAudio
): OfflineAudio = OfflineAudio.Factory.from(onlineAudio)
diff --git a/mirai-core-api/src/commonMain/kotlin/message/data/FileMessage.kt b/mirai-core-api/src/commonMain/kotlin/message/data/FileMessage.kt
index 5ee48b71b..2eca81f1b 100644
--- a/mirai-core-api/src/commonMain/kotlin/message/data/FileMessage.kt
+++ b/mirai-core-api/src/commonMain/kotlin/message/data/FileMessage.kt
@@ -26,11 +26,6 @@ import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiInternalApi
import net.mamoe.mirai.utils.NotStableForInheritance
import net.mamoe.mirai.utils.map
-import kotlin.jvm.JvmMultifileClass
-import kotlin.jvm.JvmName
-import kotlin.jvm.JvmStatic
-import kotlin.jvm.JvmSynthetic
-import kotlin.native.CName
/**
* 文件消息.
@@ -133,6 +128,5 @@ internal open class FallbackFileMessageSerializer :
* @since 2.5
*/
@JvmSynthetic
-@CName("", "FileMessage_new")
public fun FileMessage(id: String, internalId: Int, name: String, size: Long): FileMessage =
FileMessage.create(id, internalId, name, size)
\ No newline at end of file
diff --git a/mirai-core-api/src/commonMain/kotlin/message/data/FlashImage.kt b/mirai-core-api/src/commonMain/kotlin/message/data/FlashImage.kt
index d2d8a8bd8..5f4111365 100644
--- a/mirai-core-api/src/commonMain/kotlin/message/data/FlashImage.kt
+++ b/mirai-core-api/src/commonMain/kotlin/message/data/FlashImage.kt
@@ -18,9 +18,6 @@ import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiInternalApi
import net.mamoe.mirai.utils.safeCast
-import kotlin.jvm.JvmStatic
-import kotlin.jvm.JvmSynthetic
-import kotlin.native.CName
/**
* 闪照. 闪照的内容取决于 [image] 代表的图片.
@@ -97,7 +94,6 @@ public data class FlashImage(
* 将普通图片转换为闪照.
*/
@JvmSynthetic
-@CName("", "FlashImage_new")
public inline fun FlashImage(imageId: String): FlashImage = FlashImage.from(imageId)
/**
diff --git a/mirai-core-api/src/commonMain/kotlin/message/data/Image.kt b/mirai-core-api/src/commonMain/kotlin/message/data/Image.kt
index 01ad46299..75163ff7c 100644
--- a/mirai-core-api/src/commonMain/kotlin/message/data/Image.kt
+++ b/mirai-core-api/src/commonMain/kotlin/message/data/Image.kt
@@ -47,11 +47,6 @@ import net.mamoe.mirai.message.data.Image.Key.queryUrl
import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.ExternalResource.Companion.uploadAsImage
-import kotlin.jvm.JvmMultifileClass
-import kotlin.jvm.JvmName
-import kotlin.jvm.JvmStatic
-import kotlin.jvm.JvmSynthetic
-import kotlin.native.CName
/**
* 自定义表情 (收藏的表情) 和普通图片.
@@ -487,7 +482,6 @@ public interface Image : Message, MessageContent, CodableMessage {
* @see IMirai.createImage
*/
@JvmSynthetic
-@CName("", "Image_new")
public fun Image(imageId: String): Image = Builder.newBuilder(imageId).build()
/**
@@ -497,7 +491,6 @@ public fun Image(imageId: String): Image = Builder.newBuilder(imageId).build()
* @since 2.9.0
*/
@JvmSynthetic
-@CName("", "Image_new2")
public inline fun Image(imageId: String, builderAction: Builder.() -> Unit = {}): Image =
Builder.newBuilder(imageId).apply(builderAction).build()
diff --git a/mirai-core-api/src/commonMain/kotlin/message/data/UnsupportedMessage.kt b/mirai-core-api/src/commonMain/kotlin/message/data/UnsupportedMessage.kt
index fa17e78ad..ce9425db8 100644
--- a/mirai-core-api/src/commonMain/kotlin/message/data/UnsupportedMessage.kt
+++ b/mirai-core-api/src/commonMain/kotlin/message/data/UnsupportedMessage.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
+ * Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -21,11 +21,6 @@ import net.mamoe.mirai.IMirai
import net.mamoe.mirai.Mirai
import net.mamoe.mirai.message.data.visitor.MessageVisitor
import net.mamoe.mirai.utils.*
-import kotlin.jvm.JvmMultifileClass
-import kotlin.jvm.JvmName
-import kotlin.jvm.JvmStatic
-import kotlin.jvm.JvmSynthetic
-import kotlin.native.CName
/**
* mirai 尚未支持的消息类型.
@@ -81,5 +76,4 @@ public interface UnsupportedMessage : MessageContent {
* @see UnsupportedMessage.create
*/
@JvmSynthetic
-@CName("", "UnsupportedMessage_new")
public inline fun UnsupportedMessage(struct: ByteArray): UnsupportedMessage = UnsupportedMessage.create(struct)
\ No newline at end of file
diff --git a/mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.kt b/mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.kt
index 9e9ef48bd..0c6462e63 100644
--- a/mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.kt
+++ b/mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.kt
@@ -24,8 +24,6 @@ import net.mamoe.mirai.event.events.BotOfflineEvent
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.coroutineContext
-import kotlin.jvm.*
-import kotlin.native.CName
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
@@ -551,7 +549,6 @@ public open class BotConfiguration : AbstractBotConfiguration() { // open for Ja
* @since 2.3
*/
@JvmSynthetic
-@CName("", "BotConfiguration_new2")
public inline fun BotConfiguration(block: BotConfiguration.() -> Unit): BotConfiguration {
return BotConfiguration().apply(block)
}
diff --git a/mirai-core-api/src/nativeMain/kotlin/contact/Contact.kt b/mirai-core-api/src/nativeMain/kotlin/contact/Contact.kt
deleted file mode 100644
index acb15735e..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/contact/Contact.kt
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.contact
-
-import io.ktor.utils.io.core.*
-import kotlinx.coroutines.CoroutineScope
-import net.mamoe.mirai.Bot
-import net.mamoe.mirai.event.events.*
-import net.mamoe.mirai.message.MessageReceipt
-import net.mamoe.mirai.message.data.*
-import net.mamoe.mirai.utils.ExternalResource
-import net.mamoe.mirai.utils.ExternalResource.Companion.uploadAsImage
-import net.mamoe.mirai.utils.NotStableForInheritance
-import net.mamoe.mirai.utils.OverFileSizeMaxException
-import kotlin.coroutines.cancellation.CancellationException
-
-/**
- * 联系对象, 即可以与 [Bot] 互动的对象. 包含 [用户][User], 和 [群][Group].
- */
-@NotStableForInheritance
-public actual interface Contact : ContactOrBot, CoroutineScope {
- /**
- * 这个联系对象所属 [Bot].
- */
- public actual override val bot: Bot
-
- /**
- * 可以是 QQ 号码或者群号码.
- *
- * @see User.id
- * @see Group.id
- */
- public actual override val id: Long
-
- /**
- * 向这个对象发送消息.
- *
- * 单条消息最大可发送 4500 字符或 50 张图片.
- *
- * @see MessagePreSendEvent 发送消息前事件
- * @see MessagePostSendEvent 发送消息后事件
- *
- * @throws EventCancelledException 当发送消息事件被取消时抛出
- * @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
- * @throws MessageTooLargeException 当消息过长时抛出
- * @throws IllegalArgumentException 当消息内容为空时抛出 (详见 [Message.isContentEmpty])
- *
- * @return 消息回执. 可 [引用][MessageReceipt.quote] 或 [撤回][MessageReceipt.recall] 这条消息.
- */
- public actual suspend fun sendMessage(message: Message): MessageReceipt
-
- /**
- * 发送纯文本消息
- * @see sendMessage
- */
- public actual suspend fun sendMessage(message: String): MessageReceipt = sendMessage(message.toPlainText())
-
- /**
- * 上传一个 [资源][ExternalResource] 作为图片以备发送.
- *
- * **无论上传是否成功都不会关闭 [resource]. 需要调用方手动关闭资源**
- *
- * 也可以使用其他扩展: [ExternalResource.uploadAsImage] 使用 [Input] 等上传.
- *
- * @see Image 查看有关图片的更多信息, 如上传图片
- *
- * @see BeforeImageUploadEvent 图片发送前事件, 可拦截.
- * @see ImageUploadEvent 图片发送完成事件, 不可拦截.
- *
- * @see ExternalResource
- *
- * @throws EventCancelledException 当发送消息事件被取消时抛出
- * @throws OverFileSizeMaxException 当图片文件过大而被服务器拒绝上传时抛出. (最大大小约为 20 MB, 但 mirai 限制的大小为 30 MB)
- */
- public actual suspend fun uploadImage(resource: ExternalResource): Image
-
- public actual companion object {
- /**
- * 将资源作为单独的图片消息发送给 [this]
- *
- * @see Contact.sendMessage 最终调用, 发送消息.
- */
- public actual suspend fun C.sendImage(resource: ExternalResource): MessageReceipt {
- return this.uploadImage(resource).sendTo(this)
- }
-
- /**
- * 将文件作为图片上传, 但不发送
- * @throws OverFileSizeMaxException
- */
- @kotlin.internal.LowPriorityInOverloadResolution
- @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "EXTENSION_SHADOWED_BY_MEMBER")
- @Throws(OverFileSizeMaxException::class, CancellationException::class)
- public actual suspend fun Contact.uploadImage(resource: ExternalResource): Image {
- return uploadImage(resource)
- }
-
- }
-
-}
\ No newline at end of file
diff --git a/mirai-core-api/src/nativeMain/kotlin/contact/FileSupported.kt b/mirai-core-api/src/nativeMain/kotlin/contact/FileSupported.kt
deleted file mode 100644
index 39744e521..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/contact/FileSupported.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-
-package net.mamoe.mirai.contact
-
-import net.mamoe.mirai.contact.file.RemoteFiles
-import net.mamoe.mirai.utils.NotStableForInheritance
-
-/**
- * 支持文件操作的 [Contact]. 目前仅 [Group].
- *
- * 获取文件操作相关示例: [RemoteFiles]
- *
- * @since 2.5
- *
- * @see RemoteFiles
- */
-@NotStableForInheritance
-public actual interface FileSupported : Contact {
- /**
- * 获取远程文件列表 (管理器).
- *
- * @since 2.8
- */
- public actual val files: RemoteFiles
-}
\ No newline at end of file
diff --git a/mirai-core-api/src/nativeMain/kotlin/contact/file/AbsoluteFolder.kt b/mirai-core-api/src/nativeMain/kotlin/contact/file/AbsoluteFolder.kt
deleted file mode 100644
index 05981121a..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/contact/file/AbsoluteFolder.kt
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.contact.file
-
-import kotlinx.coroutines.flow.Flow
-import net.mamoe.mirai.contact.PermissionDeniedException
-import net.mamoe.mirai.utils.ExternalResource
-import net.mamoe.mirai.utils.NotStableForInheritance
-import net.mamoe.mirai.utils.ProgressionCallback
-
-/**
- * 绝对目录标识. 精确表示一个远程目录. 不会受同名文件或目录的影响.
- *
- * @since 2.8
- * @see RemoteFiles
- * @see AbsoluteFile
- * @see AbsoluteFileFolder
- */
-@Suppress("SEALED_INHERITOR_IN_DIFFERENT_MODULE")
-@NotStableForInheritance
-public actual interface AbsoluteFolder : AbsoluteFileFolder {
- /**
- * 当前快照中文件数量, 当有文件更新时(上传/删除文件) 该属性不会更新.
- *
- * 只可能通过 [refresh] 手动刷新
- *
- * 特别的, 若该目录表示根目录, [contentsCount] 返回 `0`. (无法快速获取)
- */
- public actual val contentsCount: Int
-
- /**
- * 当该目录为空时返回 `true`.
- */
- public actual fun isEmpty(): Boolean = contentsCount == 0
-
- /**
- * 返回更新了文件或目录信息 ([lastModifiedTime] 等) 的, 指向相同文件的 [AbsoluteFileFolder].
- * 不会更新当前 [AbsoluteFileFolder] 对象.
- *
- * 当远程文件或目录不存在时返回 `null`.
- *
- * 该函数会遍历上级目录的所有文件并匹配当前文件, 因此可能会非常慢, 请不要频繁使用.
- */
- actual override suspend fun refreshed(): AbsoluteFolder?
-
- ///////////////////////////////////////////////////////////////////////////
- // list children
- ///////////////////////////////////////////////////////////////////////////
-
- /**
- * 获取该目录下所有子目录列表.
- */
- public actual suspend fun folders(): Flow
-
- /**
- * 获取该目录下所有文件列表.
- */
- public actual suspend fun files(): Flow
-
-
- /**
- * 获取该目录下所有文件和子目录列表.
- */
- public actual suspend fun children(): Flow
-
- ///////////////////////////////////////////////////////////////////////////
- // resolve and upload
- ///////////////////////////////////////////////////////////////////////////
-
- /**
- * 创建一个名称为 [name] 的子目录. 返回成功创建的或已有的子目录. 当目标目录已经存在时则直接返回该目录.
- *
- * @throws IllegalArgumentException 当 [name] 为空或包含非法字符 (`:*?"<>|`) 时抛出
- * @throws PermissionDeniedException 当权限不足时抛出
- */
- public actual suspend fun createFolder(name: String): AbsoluteFolder
-
- /**
- * 获取一个已存在的名称为 [name] 的子目录. 当该名称的子目录不存在时返回 `null`.
- *
- * @throws IllegalArgumentException 当 [name] 为空或包含非法字符 (`:*?"<>|`) 时抛出
- */
- public actual suspend fun resolveFolder(name: String): AbsoluteFolder?
-
- /**
- * 获取一个已存在的 [AbsoluteFileFolder.id] 为 [id] 的子目录. 当该名称的子目录不存在时返回 `null`.
- *
- * @throws IllegalArgumentException 当 [id] 为空或无效时抛出
- *
- * @since 2.9.0
- */
- public actual suspend fun resolveFolderById(id: String): AbsoluteFolder?
-
- /**
- * 精确获取 [AbsoluteFile.id] 为 [id] 的文件. 在目标文件不存在时返回 `null`. 当 [deep] 为 `true` 时还会深入子目录查找.
- */
- public actual suspend fun resolveFileById(
- id: String,
- deep: Boolean
- ): AbsoluteFile?
-
- /**
- * 根据路径获取指向的所有路径为 [path] 的文件列表. 同时支持相对路径和绝对路径. 支持获取子目录内的文件.
- */
- public actual suspend fun resolveFiles(
- path: String
- ): Flow
-
- /**
- * 根据路径获取指向的所有路径为 [path] 的文件和目录列表. 同时支持相对路径和绝对路径. 支持获取子目录内的文件和目录.
- */
- public actual suspend fun resolveAll(
- path: String
- ): Flow
-
- /**
- * 上传一个文件到该目录, 返回上传成功的文件标识.
- *
- * 会在必要时尝试创建远程目录.
- *
- * ### [filepath]
- *
- * - 可以是 `foo.txt` 表示该目录下的文件 "foo.txt"
- * - 也可以是 `sub/foo.txt` 表示该目录的子目录 "sub" 下的文件 "foo.txt".
- * - 或是绝对路径 `/sub/foo.txt` 表示根目录的 "sub" 目录下的文件 "foo.txt"
- *
- * @param filepath 目标文件名
- * @param content 文件内容
- * @param callback 下载进度回调, 传递的 `progression` 是已下载字节数.
- *
- * @throws PermissionDeniedException 当无管理员权限时抛出 (若群仅允许管理员上传)
- */
- public actual suspend fun uploadNewFile(
- filepath: String,
- content: ExternalResource,
- callback: ProgressionCallback?,
- ): AbsoluteFile
-
- public actual companion object {
- /**
- * 根目录 folder ID.
- * @see id
- */
- public actual const val ROOT_FOLDER_ID: String = "/"
- }
-}
\ No newline at end of file
diff --git a/mirai-core-api/src/nativeMain/kotlin/contact/roaming/RoamingMessages.kt b/mirai-core-api/src/nativeMain/kotlin/contact/roaming/RoamingMessages.kt
deleted file mode 100644
index 3145ab89c..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/contact/roaming/RoamingMessages.kt
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.contact.roaming
-
-import kotlinx.coroutines.flow.Flow
-import net.mamoe.mirai.message.data.MessageChain
-import net.mamoe.mirai.message.data.MessageSource
-
-
-/**
- * 漫游消息记录管理器. 可通过 [RoamingSupported.roamingMessages] 获得.
- *
- * @since 2.8
- * @see RoamingSupported
- */
-public actual interface RoamingMessages {
- ///////////////////////////////////////////////////////////////////////////
- // Get list
- ///////////////////////////////////////////////////////////////////////////
-
- /**
- * 查询指定时间段内的漫游消息记录.
- *
- * 返回查询到的漫游消息记录, 顺序为由新到旧. 这些 [MessageChain] 与从事件中收到的消息链相似, 属于在线消息.
- * 可从 [MessageChain] 获取 [MessageSource] 来确定发送人等相关信息, 也可以进行引用回复或撤回.
- *
- * 注意, 返回的消息记录既包含机器人发送给目标用户的消息, 也包含目标用户发送给机器人的消息.
- * 可通过 [MessageChain] 获取 [MessageSource] (用法为 `messageChain.source`), 判断 [MessageSource.fromId] (发送人).
- * 消息的其他*元数据*信息也要通过 [MessageSource] 获取 (如 [MessageSource.time] 获取时间).
- *
- * 若只需要获取单向消息 (机器人发送给目标用户的消息或反之), 可使用 [RoamingMessageFilter.SENT] 或 [RoamingMessageFilter.RECEIVED] 作为 [filter] 参数传递.
- *
- * 性能提示: 请在 [filter] 执行筛选, 若 [filter] 返回 `false` 则不会解析消息链, 这对本函数的处理速度有决定性影响.
- *
- * @param timeStart 起始时间戳, 单位为秒. 可以为 `0`, 即表示从可以获取的最早的消息起. 负数将会被看是 `0`.
- * @param timeEnd 结束时间戳, 单位为秒. 可以为 [Long.MAX_VALUE], 即表示到可以获取的最晚的消息为止. 低于 [timeStart] 的值将会被看作是 [timeStart] 的值.
- * @param filter 过滤器.
- */
- public actual suspend fun getMessagesIn(
- timeStart: Long,
- timeEnd: Long,
- filter: RoamingMessageFilter?
- ): Flow
-
- /**
- * 查询所有漫游消息记录.
- *
- * 返回查询到的漫游消息记录, 顺序为由新到旧. 这些 [MessageChain] 与从事件中收到的消息链相似, 属于在线消息.
- * 可从 [MessageChain] 获取 [MessageSource] 来确定发送人等相关信息, 也可以进行引用回复或撤回.
- *
- * 注意, 返回的消息记录既包含机器人发送给目标用户的消息, 也包含目标用户发送给机器人的消息.
- * 可通过 [MessageChain] 获取 [MessageSource] (用法为 `messageChain.source`), 判断 [MessageSource.fromId] (发送人).
- * 消息的其他*元数据*信息也要通过 [MessageSource] 获取 (如 [MessageSource.time] 获取时间).
- *
- * 若只需要获取单向消息 (机器人发送给目标用户的消息或反之), 可使用 [RoamingMessageFilter.SENT] 或 [RoamingMessageFilter.RECEIVED] 作为 [filter] 参数传递.
- *
- * 性能提示: 请在 [filter] 执行筛选, 若 [filter] 返回 `false` 则不会解析消息链, 这对本函数的处理速度有决定性影响.
- *
- * @param filter 过滤器.
- */
- public actual suspend fun getAllMessages(
- filter: RoamingMessageFilter?
- ): Flow = getMessagesIn(0, Long.MAX_VALUE, filter)
-}
\ No newline at end of file
diff --git a/mirai-core-api/src/nativeMain/kotlin/event/EventChannel.kt b/mirai-core-api/src/nativeMain/kotlin/event/EventChannel.kt
deleted file mode 100644
index 10525f12b..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/event/EventChannel.kt
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.event
-
-import kotlinx.coroutines.*
-import kotlinx.coroutines.channels.Channel
-import kotlinx.coroutines.channels.ClosedSendChannelException
-import kotlinx.coroutines.channels.SendChannel
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.SharedFlow
-import kotlinx.coroutines.flow.filter
-import kotlinx.coroutines.sync.Mutex
-import net.mamoe.mirai.Bot
-import net.mamoe.mirai.IMirai
-import net.mamoe.mirai.event.ConcurrencyKind.CONCURRENT
-import net.mamoe.mirai.event.ConcurrencyKind.LOCKED
-import net.mamoe.mirai.event.events.BotEvent
-import net.mamoe.mirai.utils.*
-import kotlin.coroutines.CoroutineContext
-import kotlin.reflect.KClass
-
-/**
- * 事件通道.
- *
- * 事件通道是监听事件的入口, 但不负责广播事件. 要广播事件, 使用 [Event.broadcast] 或 [IMirai.broadcastEvent].
- *
- * ## 获取事件通道
- *
- * [EventChannel] 不可自行构造, 只能通过 [GlobalEventChannel], [BotEvent], 或基于一个通道的过滤等操作获得.
- *
- * ### 全局事件通道
- *
- * [GlobalEventChannel] 是单例对象, 表示全局事件通道, 可以获取到在其中广播的所有事件.
- *
- * ### [BotEvent] 事件通道
- *
- * 若只需要监听某个 [Bot] 的事件, 可通过 [Bot.eventChannel] 获取到这样的 [EventChannel].
- *
- * ## 通道操作
- *
- * ### 对通道的操作
- * - 过滤通道: 通过 [EventChannel.filter]. 例如 `filter { it is BotEvent }` 得到一个只能监听到 [BotEvent] 的事件通道.
- * - 转换为 Kotlin 协程 [Channel]: [EventChannel.forwardToChannel]
- * - 添加 [CoroutineContext]: [context], [parentJob], [parentScope], [exceptionHandler]
- *
- * ### 创建事件监听
- * - [EventChannel.subscribe] 创建带条件的一个事件监听器.
- * - [EventChannel.subscribeAlways] 创建一个总是监听事件的事件监听器.
- * - [EventChannel.subscribeOnce] 创建一个只监听单次的事件监听器.
- *
- * ### 监听器生命周期
- *
- * 阅读 [EventChannel.subscribe] 以获取监听器生命周期相关信息.
- *
- * ## 与 kotlinx-coroutines 交互
- *
- * mirai [EventChannel] 设计比 kotlinx-coroutines 的 [Flow] 稳定版更早.
- * [EventChannel] 的功能与 [Flow] 类似, 不过 [EventChannel] 在 [subscribe] (类似 [Flow.collect]) 时有优先级判定, 也允许[拦截][Event.intercept].
- *
- * ### 通过 [Flow] 接收事件
- *
- * 使用 [EventChannel.asFlow] 获得 [Flow], 然后可使用 [Flow.collect] 等操作.
- *
- * ### 转发事件到 [SendChannel]
- *
- * 使用 [EventChannel.forwardToChannel] 可将事件转发到指定 [SendChannel].
- */
-@NotStableForInheritance // since 2.12, before it was `final class`.
-public actual abstract class EventChannel @MiraiInternalApi public actual constructor(
- public actual val baseEventClass: KClass,
- /**
- * 此事件通道的默认 [CoroutineScope.coroutineContext]. 将会被添加给所有注册的事件监听器.
- */
- public actual val defaultCoroutineContext: CoroutineContext,
-) {
-
- /**
- * 创建事件监听并将监听结果转发到 [channel]. 当 [Channel.send] 抛出 [ClosedSendChannelException] 时停止 [Listener] 监听和转发.
- *
- * 返回创建的会转发监听到的所有事件到 [channel] 的[事件监听器][Listener]. [停止][Listener.complete] 该监听器会停止转发, 不会影响目标 [channel].
- *
- * 若 [Channel.send] 挂起, 则监听器也会挂起, 也就可能会导致事件广播过程挂起.
- *
- * 示例:
- *
- * ```
- * val eventChannel: EventChannel = ...
- * val channel = Channel() // kotlinx.coroutines.channels.Channel
- * eventChannel.forwardToChannel(channel, priority = ...)
- *
- * // 其他地方
- * val event: BotEvent = channel.receive() // 挂起并接收一个事件
- * ```
- *
- * @see subscribeAlways
- * @see Channel
- * @since 2.10
- */
- public actual fun forwardToChannel(
- channel: SendChannel<@UnsafeVariance BaseEvent>,
- coroutineContext: CoroutineContext,
- priority: EventPriority,
- ): Listener<@UnsafeVariance BaseEvent> {
- // keep this LOCKED, otherwise compiler will choose the 'inline subscribe' which takes no KClass arg.
- return subscribe(baseEventClass, coroutineContext, LOCKED, priority) {
- try {
- channel.send(it)
- ListeningStatus.LISTENING
- } catch (_: ClosedSendChannelException) {
- ListeningStatus.STOPPED
- }
- }
- }
-
- /**
- * 通过 [Flow] 接收此通道内的所有事件.
- *
- * ```
- * val eventChannel: EventChannel = ...
- * val flow: Flow = eventChannel.asFlow()
- *
- * flow.collect { // it
- * //
- * }
- *
- * flow.filterIsInstance.collect { // it: GroupMessageEvent
- * // 处理事件 ...
- * }
- *
- * flow.filterIsInstance.collect { // it: FriendMessageEvent
- * // 处理事件 ...
- * }
- * ```
- *
- * 类似于 [SharedFlow], [EventChannel.asFlow] 返回的 [Flow] 永远都不会停止. 因此上述示例 [Flow.collect] 永远都不会正常 (以抛出异常之外的) 结束.
- *
- * 通过 [asFlow] 接收事件相当于通过 [subscribeAlways] 以 [EventPriority.MONITOR] 监听事件.
- *
- * **注意**: [context], [parentJob] 等控制 [EventChannel.defaultCoroutineContext] 的操作对 [asFlow] 无效. 因为 [asFlow] 并不创建协程.
- *
- * @see Flow
- * @since 2.12
- */
- public actual abstract fun asFlow(): Flow
-
- // region transforming operations
-
- /**
- * 添加一个过滤器. 过滤器将在收到任何事件之后, 传递给通过 [EventChannel.subscribe] 注册的监听器之前调用.
- *
- * 若 [filter] 返回 `true`, 该事件将会被传给监听器. 否则将会被忽略, **监听器继续监听**.
- *
- * ## 线性顺序
- * 多个 [filter] 的处理是线性且有顺序的. 若一个 [filter] 已经返回了 `false` (代表忽略这个事件), 则会立即忽略, 而不会传递给后续过滤器.
- *
- * 示例:
- * ```
- * GlobalEventChannel // GlobalEventChannel 会收到全局所有事件, 事件类型是 Event
- * .filterIsInstance() // 过滤, 只接受 BotEvent
- * .filter { event: BotEvent ->
- * // 此时的 event 一定是 BotEvent
- * event.bot.id == 123456 // 再过滤 event 的 bot.id
- * }
- * .subscribeAlways { event: BotEvent ->
- * // 现在 event 是 BotEvent, 且 bot.id == 123456
- * }
- * ```
- *
- * ## 过滤器挂起
- * [filter] 允许挂起协程. **过滤器的挂起将被认为是事件监听器的挂起**.
- *
- * 过滤器挂起是否会影响事件处理,
- * 取决于 [subscribe] 时的 [ConcurrencyKind] 和 [EventPriority].
- *
- * ## 过滤器异常处理
- * 若 [filter] 抛出异常, 将被包装为 [ExceptionInEventChannelFilterException] 并重新抛出.
- *
- * @see filterIsInstance 过滤指定类型的事件
- */
- public actual fun filter(filter: suspend (event: BaseEvent) -> Boolean): EventChannel {
- return FilterEventChannel(this, filter)
- }
-
- /**
- * [EventChannel.filter] 的 Java 版本.
- *
- * 添加一个过滤器. 过滤器将在收到任何事件之后, 传递给通过 [EventChannel.subscribe] 注册的监听器之前调用.
- *
- * 若 [filter] 返回 `true`, 该事件将会被传给监听器. 否则将会被忽略, **监听器继续监听**.
- *
- * ## 线性顺序
- * 多个 [filter] 的处理是线性且有顺序的. 若一个 [filter] 已经返回了 `false` (代表忽略这个事件), 则会立即忽略, 而不会传递给后续过滤器.
- *
- * 示例:
- * ```
- * GlobalEventChannel // GlobalEventChannel 会收到全局所有事件, 事件类型是 Event
- * .filterIsInstance(BotEvent.class) // 过滤, 只接受 BotEvent
- * .filter(event ->
- * // 此时的 event 一定是 BotEvent
- * event.bot.id == 123456 // 再过滤 event 的 bot.id
- * )
- * .subscribeAlways(event -> {
- * // 现在 event 是 BotEvent, 且 bot.id == 123456
- * })
- * ```
- *
- * ## 过滤器阻塞
- * [filter] 允许阻塞线程. **过滤器的阻塞将被认为是事件监听器的阻塞**.
- *
- * 过滤器阻塞是否会影响事件处理,
- * 取决于 [subscribe] 时的 [ConcurrencyKind] 和 [EventPriority].
- *
- * ## 过滤器异常处理
- * 若 [filter] 抛出异常, 将被包装为 [ExceptionInEventChannelFilterException] 并重新抛出.
- *
- * @see filterIsInstance 过滤指定类型的事件
- *
- * @since 2.2
- */
- @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
- @kotlin.internal.LowPriorityInOverloadResolution
- public actual fun filter(filter: (event: BaseEvent) -> Boolean): EventChannel {
- return filter { runBIO { filter(it) } }
- }
-
- /**
- * 过滤事件的类型. 返回一个只包含 [E] 类型事件的 [EventChannel]
- * @see filter 获取更多信息
- */
- public actual inline fun filterIsInstance(): EventChannel =
- filterIsInstance(E::class)
-
- /**
- * 过滤事件的类型. 返回一个只包含 [E] 类型事件的 [EventChannel]
- * @see filter 获取更多信息
- */
- public actual fun filterIsInstance(kClass: KClass): EventChannel {
- return filter { kClass.isInstance(it) }.cast()
- }
-
- /**
- * 创建一个新的 [EventChannel], 该 [EventChannel] 包含 [`this.coroutineContext`][defaultCoroutineContext] 和添加的 [coroutineContexts].
- * [coroutineContexts] 会覆盖 [defaultCoroutineContext] 中的重复元素.
- *
- * 此操作不会修改 [`this.coroutineContext`][defaultCoroutineContext], 只会创建一个新的 [EventChannel].
- */
- public actual abstract fun context(vararg coroutineContexts: CoroutineContext): EventChannel
-
- /**
- * 创建一个新的 [EventChannel], 该 [EventChannel] 包含 [this.coroutineContext][defaultCoroutineContext] 和添加的 [coroutineExceptionHandler]
- * @see context
- */
- @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
- @kotlin.internal.LowPriorityInOverloadResolution
- public actual fun exceptionHandler(coroutineExceptionHandler: CoroutineExceptionHandler): EventChannel {
- return context(coroutineExceptionHandler)
- }
-
- /**
- * 创建一个新的 [EventChannel], 该 [EventChannel] 包含 [`this.coroutineContext`][defaultCoroutineContext] 和添加的 [coroutineExceptionHandler]
- * @see context
- */
- public actual fun exceptionHandler(coroutineExceptionHandler: (exception: Throwable) -> Unit): EventChannel {
- return context(CoroutineExceptionHandler { _, throwable ->
- coroutineExceptionHandler(throwable)
- })
- }
-
- /**
- * 将 [coroutineScope] 作为这个 [EventChannel] 的父作用域.
- *
- * 实际作用为创建一个新的 [EventChannel],
- * 该 [EventChannel] 包含 [`this.coroutineContext`][defaultCoroutineContext] 和添加的 [CoroutineScope.coroutineContext],
- * 并以 [CoroutineScope] 中 [Job] (如果有) [作为父 Job][parentJob]
- *
- * @see parentJob
- * @see context
- *
- * @see CoroutineScope.globalEventChannel `GlobalEventChannel.parentScope()` 的扩展
- */
- public actual fun parentScope(coroutineScope: CoroutineScope): EventChannel {
- return context(coroutineScope.coroutineContext)
- }
-
- /**
- * 指定协程父 [Job]. 之后在此 [EventChannel] 下创建的事件监听器都会成为 [job] 的子任务, 当 [job] 被取消时, 所有的事件监听器都会被取消.
- *
- * 注意: 监听器不会失败 ([Job.cancel]). 监听器处理过程的异常都会被捕获然后交由 [CoroutineExceptionHandler] 处理, 因此 [job] 不会因为子任务监听器的失败而被取消.
- *
- * @see parentScope
- * @see context
- */
- public actual fun parentJob(job: Job): EventChannel {
- return context(job)
- }
-
- // endregion
-
- // region subscribe
-
- /**
- * 创建一个事件监听器, 监听事件通道中所有 [E] 及其子类事件.
- *
- * 每当 [事件广播][Event.broadcast] 时, [handler] 都会被执行.
- *
- *
- * ## 创建监听
- * 调用本函数:
- * ```
- * eventChannel.subscribe { /* 会收到此通道中的所有是 E 的事件 */ }
- * ```
- *
- * ## 生命周期
- *
- * ### 通过协程作用域管理监听器
- * 本函数将会创建一个 [Job], 成为 [parentJob] 中的子任务. 可创建一个 [CoroutineScope] 来管理所有的监听器:
- * ```
- * val scope = CoroutineScope(SupervisorJob())
- *
- * val scopedChannel = eventChannel.parentScope(scope) // 将协程作用域 scope 附加到这个 EventChannel
- *
- * scopedChannel.subscribeAlways { /* ... */ } // 启动监听, 监听器协程会作为 scope 的子任务
- * scopedChannel.subscribeAlways { /* ... */ } // 启动监听, 监听器协程会作为 scope 的子任务
- *
- * scope.cancel() // 停止了协程作用域, 也就取消了两个监听器
- * ```
- *
- * 这个函数返回 [Listener], 它是一个 [CompletableJob]. 它会成为 [parentJob] 或 [parentScope] 的一个 [子任务][Job]
- *
- * ### 停止监听
- * 如果 [handler] 返回 [ListeningStatus.STOPPED] 监听器将被停止.
- *
- * 也可以通过 [subscribe] 返回值 [Listener] 的 [Listener.complete]
- *
- * ## 监听器调度
- * 监听器会被创建一个协程任务, 语义上在 [parentScope] 下运行.
- * 通过 Kotlin [默认协程调度器][Dispatchers.Default] 在固定的全局共享线程池里执行, 除非有 [coroutineContext] 指定.
- *
- * 默认在 [handler] 中不能处理阻塞任务. 阻塞任务将会阻塞一个 Kotlin 全局协程调度线程并可能导致严重问题.
- * 请通过 `withContext(Dispatchers.IO) { }` 等方法执行阻塞工作.
- *
- * ## 异常处理
- *
- * **监听过程抛出的异常是需要尽可能避免的, 因为这将产生不确定性.**
- *
- * 当参数 [handler] 处理事件抛出异常时, 只会从监听方协程上下文 ([CoroutineContext]) 寻找 [CoroutineExceptionHandler] 处理异常, 即如下顺序:
- * 1. 本函数参数 [coroutineContext]
- * 2. [EventChannel.defaultCoroutineContext]
- * 3. 若以上步骤无法获取 [CoroutineExceptionHandler], 则只会在日志记录异常.
- * 因此建议先指定 [CoroutineExceptionHandler] (可通过 [EventChannel.exceptionHandler]) 再监听事件, 或者在监听事件中捕获异常.
- *
- * 因此, 广播方 ([Event.broadcast]) 不会知晓监听方产生的异常, 其 [Event.broadcast] 过程也不会因监听方产生异常而提前结束.
- *
- * ***备注***: 在 2.11 以前, 发生上述异常时还会从广播方和有关 [Bot] 协程域获取 [CoroutineExceptionHandler]. 因此行为不稳定而在 2.11 变更为上述过程.
- *
- * 事件处理时抛出异常不会停止监听器.
- *
- * 建议在事件处理中 (即 [handler] 里) 处理异常,
- * 或在参数 [coroutineContext] 中添加 [CoroutineExceptionHandler], 或通过 [EventChannel.exceptionHandler].
- *
- * ## 并发安全性
- * 基于 [concurrency] 参数, 事件监听器可以被允许并行执行.
- *
- * - 若 [concurrency] 为 [ConcurrencyKind.CONCURRENT], [handler] 可能被并行调用, 需要保证并发安全.
- * - 若 [concurrency] 为 [ConcurrencyKind.LOCKED], [handler] 会被 [Mutex] 限制, 串行异步执行.
- *
- * ## 衍生监听方法
- *
- * 这些方法仅 Kotlin 可用.
- *
- * - [syncFromEvent]: 挂起当前协程, 监听一个事件, 并尝试从这个事件中**获取**一个值
- * - [nextEvent]: 挂起当前协程, 直到监听到特定类型事件的广播并通过过滤器, 返回这个事件实例.
- *
- * @param coroutineContext 在 [defaultCoroutineContext] 的基础上, 给事件监听协程的额外的 [CoroutineContext].
- * @param concurrency 并发类型. 查看 [ConcurrencyKind]
- * @param priority 监听优先级,优先级越高越先执行
- * @param handler 事件处理器. 在接收到事件时会调用这个处理器. 其返回值意义参考 [ListeningStatus]. 其异常处理参考上文
- *
- * @return 监听器实例. 此监听器已经注册到指定事件上, 在事件广播时将会调用 [handler]
- *
- *
- * @see selectMessages 以 `when` 的语法 '选择' 即将到来的一条消息.
- * @see whileSelectMessages 以 `when` 的语法 '选择' 即将到来的所有消息, 直到不满足筛选结果.
- *
- * @see subscribeAlways 一直监听
- * @see subscribeOnce 只监听一次
- *
- * @see subscribeMessages 监听消息 DSL
- */
- public actual inline fun subscribe(
- coroutineContext: CoroutineContext,
- concurrency: ConcurrencyKind,
- priority: EventPriority,
- noinline handler: suspend E.(E) -> ListeningStatus,
- ): Listener = subscribe(E::class, coroutineContext, concurrency, priority, handler)
-
- /**
- * 与 [subscribe] 的区别是接受 [eventClass] 参数, 而不使用 `reified` 泛型. 通常推荐使用具体化类型参数.
- *
- * @return 监听器实例. 此监听器已经注册到指定事件上, 在事件广播时将会调用 [handler]
- * @see subscribe
- */
- public actual fun subscribe(
- eventClass: KClass,
- coroutineContext: CoroutineContext,
- concurrency: ConcurrencyKind,
- priority: EventPriority,
- handler: suspend E.(E) -> ListeningStatus,
- ): Listener = subscribeInternal(
- eventClass,
- createListener0(coroutineContext, concurrency, priority) { it.handler(it); }
- )
-
- /**
- * 创建一个事件监听器, 监听事件通道中所有 [E] 及其子类事件.
- * 每当 [事件广播][Event.broadcast] 时, [handler] 都会被执行.
- *
- * 可在任意时候通过 [Listener.complete] 来主动停止监听.
- *
- * @param concurrency 并发类型默认为 [CONCURRENT]
- * @param coroutineContext 在 [defaultCoroutineContext] 的基础上, 给事件监听协程的额外的 [CoroutineContext]
- * @param priority 处理优先级, 优先级高的先执行
- *
- * @return 监听器实例. 此监听器已经注册到指定事件上, 在事件广播时将会调用 [handler]
- *
- * @see subscribe 获取更多说明
- */
- public actual inline fun subscribeAlways(
- coroutineContext: CoroutineContext,
- concurrency: ConcurrencyKind,
- priority: EventPriority,
- noinline handler: suspend E.(E) -> Unit,
- ): Listener = subscribeAlways(E::class, coroutineContext, concurrency, priority, handler)
-
-
- /**
- * @see subscribe
- * @see subscribeAlways
- */
- public actual fun subscribeAlways(
- eventClass: KClass,
- coroutineContext: CoroutineContext,
- concurrency: ConcurrencyKind,
- priority: EventPriority,
- handler: suspend E.(E) -> Unit,
- ): Listener = subscribeInternal(
- eventClass,
- createListener0(coroutineContext, concurrency, priority) { it.handler(it); ListeningStatus.LISTENING }
- )
-
- /**
- * 创建一个事件监听器, 监听事件通道中所有 [E] 及其子类事件, 只监听一次.
- * 当 [事件广播][Event.broadcast] 时, [handler] 会被执行.
- *
- * 可在任意时候通过 [Listener.complete] 来主动停止监听.
- *
- * @param coroutineContext 在 [defaultCoroutineContext] 的基础上, 给事件监听协程的额外的 [CoroutineContext]
- * @param priority 处理优先级, 优先级高的先执行
- *
- * @see subscribe 获取更多说明
- */
- public actual inline fun subscribeOnce(
- coroutineContext: CoroutineContext,
- priority: EventPriority,
- noinline handler: suspend E.(E) -> Unit,
- ): Listener = subscribeOnce(E::class, coroutineContext, priority, handler)
-
- /**
- * @see subscribeOnce
- */
- public actual fun subscribeOnce(
- eventClass: KClass,
- coroutineContext: CoroutineContext,
- priority: EventPriority,
- handler: suspend E.(E) -> Unit,
- ): Listener = subscribeInternal(
- eventClass,
- createListener0(coroutineContext, ConcurrencyKind.LOCKED, priority) { it.handler(it); ListeningStatus.STOPPED }
- )
-
- // endregion
-
- // region impl
-
-
- // protected, to hide from users
- @MiraiInternalApi
- protected actual abstract fun registerListener(eventClass: KClass, listener: Listener)
-
- // to overcome visibility issue
- @OptIn(MiraiInternalApi::class)
- internal actual fun registerListener0(eventClass: KClass, listener: Listener) {
- return registerListener(eventClass, listener)
- }
-
- private fun , E : Event> subscribeInternal(eventClass: KClass, listener: L): L {
- registerListener0(eventClass, listener)
- return listener
- }
-
- /**
- * Creates [Listener] instance using the [listenerBlock] action.
- */
-// @Contract("_ -> new") // always creates new instance
- @MiraiInternalApi
- protected actual abstract fun createListener(
- coroutineContext: CoroutineContext,
- concurrencyKind: ConcurrencyKind,
- priority: EventPriority,
- listenerBlock: suspend (E) -> ListeningStatus,
- ): Listener
-
- // to overcome visibility issue
- @OptIn(MiraiInternalApi::class)
- internal actual fun createListener0(
- coroutineContext: CoroutineContext,
- concurrencyKind: ConcurrencyKind,
- priority: EventPriority,
- listenerBlock: suspend (E) -> ListeningStatus,
- ): Listener = createListener(coroutineContext, concurrencyKind, priority, listenerBlock)
-
- // endregion
-}
diff --git a/mirai-core-api/src/nativeMain/kotlin/event/MessageSelectBuilderUnit.kt b/mirai-core-api/src/nativeMain/kotlin/event/MessageSelectBuilderUnit.kt
deleted file mode 100644
index 09e599463..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/event/MessageSelectBuilderUnit.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.event
-
-import net.mamoe.mirai.event.events.MessageEvent
-import net.mamoe.mirai.utils.MiraiInternalApi
-
-/**
- * [selectMessagesUnit] 或 [selectMessages] 时的 DSL 构建器.
- *
- * 它是特殊化的消息监听 ([EventChannel.subscribeMessages]) DSL
- *
- * @see MessageSubscribersBuilder 查看上层 API
- */
-@OptIn(MiraiInternalApi::class)
-public actual abstract class MessageSelectBuilderUnit @PublishedApi internal actual constructor(
- ownerMessagePacket: M,
- stub: Any?,
- subscriber: (M.(String) -> Boolean, MessageListener) -> Unit
-) : CommonMessageSelectBuilderUnit(ownerMessagePacket, stub, subscriber)
\ No newline at end of file
diff --git a/mirai-core-api/src/nativeMain/kotlin/internal/message/overwritePolymorphicWith.kt b/mirai-core-api/src/nativeMain/kotlin/internal/message/overwritePolymorphicWith.kt
deleted file mode 100644
index a530e025a..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/internal/message/overwritePolymorphicWith.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.message
-
-import kotlinx.serialization.KSerializer
-import kotlinx.serialization.modules.SerializersModule
-import kotlin.reflect.KClass
-
-internal actual fun SerializersModule.overwritePolymorphicWith(
- type: KClass,
- serializer: KSerializer
-): SerializersModule {
- throw UnsupportedOperationException("overwritePolymorphicWith is not supported on native.")
-}
\ No newline at end of file
diff --git a/mirai-core-api/src/nativeMain/kotlin/internal/utils/ExternalResourceImplByByteArray.kt b/mirai-core-api/src/nativeMain/kotlin/internal/utils/ExternalResourceImplByByteArray.kt
deleted file mode 100644
index 5cdd53881..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/internal/utils/ExternalResourceImplByByteArray.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.utils
-
-import io.ktor.utils.io.core.*
-import kotlinx.coroutines.CompletableDeferred
-import net.mamoe.mirai.utils.*
-
-internal class ExternalResourceImplByByteArray(
- private val data: ByteArray,
- formatName: String?
-) : ExternalResource {
- override val size: Long = data.size.toLong()
- override val md5: ByteArray by lazy { data.md5() }
- override val sha1: ByteArray by lazy { data.sha1() }
- override val formatName: String by lazy {
- formatName ?: getFileType(data.copyOf(COUNT_BYTES_USED_FOR_DETECTING_FILE_TYPE))
- ?: ExternalResource.DEFAULT_FORMAT_NAME
- }
- override val closed: CompletableDeferred = CompletableDeferred()
- override val origin: Any
- get() = data//.clone()
-
- @MiraiInternalApi
- override fun input(): Input = ByteReadPacket(data)
-
- override fun close() {
- kotlin.runCatching { closed.complete(Unit) }
- }
-}
diff --git a/mirai-core-api/src/nativeMain/kotlin/internal/utils/Marker.kt b/mirai-core-api/src/nativeMain/kotlin/internal/utils/Marker.kt
deleted file mode 100644
index 801bc1440..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/internal/utils/Marker.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.utils
-
-internal actual interface Marker {
- actual fun addParents(vararg parent: Marker)
-}
-
-internal class MarkerImpl(
- private val name: String
-) : Marker {
- override fun addParents(vararg parent: Marker) {
- }
-}
\ No newline at end of file
diff --git a/mirai-core-api/src/nativeMain/kotlin/internal/utils/MarkerManager.kt b/mirai-core-api/src/nativeMain/kotlin/internal/utils/MarkerManager.kt
deleted file mode 100644
index 352122dd6..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/internal/utils/MarkerManager.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.utils
-
-internal actual object MarkerManager {
- actual fun getMarker(name: String): Marker {
- return MarkerImpl(name)
- }
-}
\ No newline at end of file
diff --git a/mirai-core-api/src/nativeMain/kotlin/message/action/AsyncRecallResult.kt b/mirai-core-api/src/nativeMain/kotlin/message/action/AsyncRecallResult.kt
deleted file mode 100644
index cb8ce069f..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/message/action/AsyncRecallResult.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.message.action
-
-import kotlinx.coroutines.CompletableDeferred
-import kotlinx.coroutines.Deferred
-import net.mamoe.mirai.message.data.MessageSource
-import net.mamoe.mirai.message.data.MessageSource.Key.recallIn
-
-/**
- * 异步撤回结果.
- *
- * 可由 [MessageSource.recallIn] 返回得到.
- *
- * ## 用法
- *
- * ### 获取撤回失败时的异常
- *
- * ```
- * val exception = result.exception.await() // 挂起协程并等待撤回的结果.
- * if (exception == null) {
- * // 撤回成功
- * } else {
- * // 撤回失败
- * }
- * ```
- *
- * 若仅需要了解撤回是否成功而不需要获取详细异常实例, 可使用 [isSuccess]
- *
- * @see MessageSource.recallIn
- */
-public actual class AsyncRecallResult internal actual constructor(
- /**
- * 撤回时产生的异常, 当撤回成功时为 `null`.
- */
- public actual val exception: Deferred,
-) {
- /**
- * 撤回是否成功.
- */
- public actual val isSuccess: Deferred by lazy {
- CompletableDeferred().apply {
- exception.invokeOnCompletion {
- complete(it == null)
- }
- }
- }
-
- /**
- * 挂起协程直到撤回完成, 返回撤回时产生的异常. 当撤回成功时返回 `null`.
- */
- public actual suspend fun awaitException(): Throwable? {
- return exception.await()
- }
-
- /**
- * 挂起协程直到撤回完成, 返回撤回的结果.
- */
- public actual suspend fun awaitIsSuccess(): Boolean {
- return isSuccess.await()
- }
-}
diff --git a/mirai-core-api/src/nativeMain/kotlin/message/data/FileMessage.kt b/mirai-core-api/src/nativeMain/kotlin/message/data/FileMessage.kt
deleted file mode 100644
index f458f4e24..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/message/data/FileMessage.kt
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.message.data
-
-import kotlinx.serialization.KSerializer
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-import net.mamoe.mirai.Mirai
-import net.mamoe.mirai.contact.FileSupported
-import net.mamoe.mirai.contact.file.AbsoluteFile
-import net.mamoe.mirai.event.events.MessageEvent
-import net.mamoe.mirai.message.code.CodableMessage
-import net.mamoe.mirai.message.code.internal.appendStringAsMiraiCode
-import net.mamoe.mirai.message.data.visitor.MessageVisitor
-import net.mamoe.mirai.utils.MiraiExperimentalApi
-import net.mamoe.mirai.utils.MiraiInternalApi
-import net.mamoe.mirai.utils.NotStableForInheritance
-import net.mamoe.mirai.utils.safeCast
-
-/**
- * 文件消息.
- *
- * [name] 与 [size] 只供本地使用, 发送消息时只会使用 [id] 和 [internalId].
- *
- * 注: [FileMessage] 不可二次发送
- *
- * ### 文件操作
- * 要下载这个文件, 可通过 [toAbsoluteFile] 获取到 [AbsoluteFile] 然后操作.
- *
- * 要获取到 [FileMessage], 可以通过 [MessageEvent.message] 获取, 或通过 [AbsoluteFile.toMessage] 得到.
- *
- * @since 2.5
- * @suppress [FileMessage] 的使用是稳定的, 但自行实现不稳定.
- */
-@Serializable(FileMessage.Serializer::class)
-@SerialName(FileMessage.SERIAL_NAME)
-@NotStableForInheritance
-public actual interface FileMessage : MessageContent, ConstrainSingle, CodableMessage {
- /**
- * 服务器需要的某种 ID.
- */
- public actual val id: String
-
- /**
- * 服务器需要的某种 ID.
- */
- public actual val internalId: Int
-
- /**
- * 文件名
- */
- public actual val name: String
-
- /**
- * 文件大小 bytes
- */
- public actual val size: Long
-
- actual override fun contentToString(): String = "[文件]$name" // orthodox
-
- @MiraiExperimentalApi
- actual override fun appendMiraiCodeTo(builder: StringBuilder) {
- builder.append("[mirai:file:")
- builder.appendStringAsMiraiCode(id).append(",")
- builder.append(internalId).append(",")
- builder.appendStringAsMiraiCode(name).append(",")
- builder.append(size).append("]")
- }
-
- /**
- * 获取一个对应的 [AbsoluteFile]. 当目标群或好友不存在这个文件时返回 `null`.
- *
- * @since 2.8
- */
- public actual suspend fun toAbsoluteFile(contact: FileSupported): AbsoluteFile?
-
- actual override val key: Key get() = Key
-
- @MiraiInternalApi
- actual override fun accept(visitor: MessageVisitor, data: D): R {
- return visitor.visitFileMessage(this, data)
- }
-
- /**
- * 注意, baseKey [MessageContent] 不稳定. 未来可能会有变更.
- */
- public actual companion object Key :
- AbstractPolymorphicMessageKey(
- MessageContent, { it.safeCast() }) {
-
- public actual const val SERIAL_NAME: String = "FileMessage"
-
- /**
- * 构造 [FileMessage]
- * @since 2.5
- */
- public actual fun create(id: String, internalId: Int, name: String, size: Long): FileMessage =
- Mirai.createFileMessage(id, internalId, name, size)
- }
-
- public actual object Serializer :
- KSerializer by @OptIn(MiraiInternalApi::class) FallbackFileMessageSerializer()
-}
diff --git a/mirai-core-api/src/nativeMain/kotlin/package.kt b/mirai-core-api/src/nativeMain/kotlin/package.kt
deleted file mode 100644
index 8a63cebca..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/package.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai
diff --git a/mirai-core-api/src/nativeMain/kotlin/utils/BotConfiguration.kt b/mirai-core-api/src/nativeMain/kotlin/utils/BotConfiguration.kt
deleted file mode 100644
index 9d5fbc47c..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/utils/BotConfiguration.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import io.ktor.utils.io.core.*
-import net.mamoe.mirai.Bot
-
-/**
- * [BotConfiguration] 的 Native 平台特别配置
- * @since 2.15
- */
-@NotStableForInheritance
-public actual abstract class AbstractBotConfiguration { // open for Java
- protected actual abstract var deviceInfo: ((Bot) -> DeviceInfo)?
- protected actual abstract var networkLoggerSupplier: ((Bot) -> MiraiLogger)
- protected actual abstract var botLoggerSupplier: ((Bot) -> MiraiLogger)
-
- /**
- * 工作目录. 默认为当前目录
- */
- public var workingDir: String = "."
-
- /**
- * 使用文件存储设备信息.
- *
- * 此函数只在 JVM 和 Android 有效. 在其他平台将会抛出异常.
- * @param filepath 文件路径. 默认是相对于 [workingDir] 的文件 "device.json".
- * @see deviceInfo
- */
- @BotConfiguration.ConfigurationDsl
- public actual fun fileBasedDeviceInfo(filepath: String) {
- deviceInfo = {
- val file = MiraiFile.create(workingDir).resolve(filepath)
- if (!file.exists()) {
- file.writeText(DeviceInfoManager.serialize(DeviceInfo.random(), BotConfiguration.json))
- }
- DeviceInfoManager.deserialize(file.readText(), BotConfiguration.json) {
- file.writeText(DeviceInfoManager.serialize(it, BotConfiguration.json))
- }
-
- }
- }
-
- /**
- * 缓存数据目录路径. 若 [cacheDir] 为绝对路径, 将解析该绝对路径, 否则作为相对于 [workingDir] 的路径解析.
- * 例如, `cache` 将会解析为 `$workingDir/cache`, 而 `/Users/Chisato/Desktop/bot/cache` 指代绝对路径, 将解析为绝对路径.
- *
- * 缓存目录保存的内容均属于不稳定的 Mirai 内部数据, 请不要手动修改它们. 清空缓存不会影响功能. 只会导致一些操作如读取全部群列表要重新进行.
- * 默认启用的缓存可以加快登录过程.
- *
- * 注意: 这个目录只存储能在 [BotConfiguration] 配置的内容, 即包含:
- * - 联系人列表
- * - 登录服务器列表
- * - 资源服务秘钥
- *
- * 其他内容如通过 [Input] 发送图片时的缓存使用 [FileCacheStrategy], 默认使用系统临时文件且会在关闭时删除文件.
- *
- * @since 2.4
- */
- public var cacheDir: String = "cache"
-
- internal actual fun applyMppCopy(new: BotConfiguration) {
- new.workingDir = workingDir
- new.cacheDir = cacheDir
- }
-}
\ No newline at end of file
diff --git a/mirai-core-api/src/nativeMain/kotlin/utils/DeviceInfo.kt b/mirai-core-api/src/nativeMain/kotlin/utils/DeviceInfo.kt
deleted file mode 100644
index ff21cdb40..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/utils/DeviceInfo.kt
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import kotlinx.serialization.Serializable
-import kotlinx.serialization.Transient
-import kotlin.random.Random
-
-/**
- * 表示设备信息
- * @see DeviceInfoBuilder
- */
-@Serializable(DeviceInfoV1LegacySerializer::class)
-public actual class DeviceInfo
-@Deprecated(DeviceInfoConstructorDeprecationMessage, level = DeprecationLevel.WARNING)
-@DeprecatedSinceMirai(warningSince = "2.15") // planned internal
-public actual constructor(
- public actual val display: ByteArray,
- public actual val product: ByteArray,
- public actual val device: ByteArray,
- public actual val board: ByteArray,
- public actual val brand: ByteArray,
- public actual val model: ByteArray,
- public actual val bootloader: ByteArray,
- public actual val fingerprint: ByteArray,
- public actual val bootId: ByteArray,
- public actual val procVersion: ByteArray,
- public actual val baseBand: ByteArray,
- public actual val version: Version,
- public actual val simInfo: ByteArray,
- public actual val osType: ByteArray,
- public actual val macAddress: ByteArray,
- public actual val wifiBSSID: ByteArray,
- public actual val wifiSSID: ByteArray,
- public actual val imsiMd5: ByteArray,
- public actual val imei: String,
- public actual val apn: ByteArray,
- public actual val androidId: ByteArray,
-) {
- public actual val ipAddress: ByteArray get() = byteArrayOf(192.toByte(), 168.toByte(), 1, 123)
-
- init {
- require(imsiMd5.size == 16) { "Bad `imsiMd5.size`. Required 16, given ${imsiMd5.size}." }
- }
-
- @Transient
- @MiraiInternalApi
- public actual val guid: ByteArray = generateGuid(androidId, macAddress)
-
- @Serializable
- public actual class Version actual constructor(
- public actual val incremental: ByteArray,
- public actual val release: ByteArray,
- public actual val codename: ByteArray,
- public actual val sdk: Int
- ) {
- /**
- * @since 2.9
- */
- actual override fun equals(other: Any?): Boolean {
- if (this === other) return true
- if (other !is Version) return false
-
- if (!incremental.contentEquals(other.incremental)) return false
- if (!release.contentEquals(other.release)) return false
- if (!codename.contentEquals(other.codename)) return false
- if (sdk != other.sdk) return false
-
- return true
- }
-
- /**
- * @since 2.9
- */
- actual override fun hashCode(): Int {
- var result = incremental.contentHashCode()
- result = 31 * result + release.contentHashCode()
- result = 31 * result + codename.contentHashCode()
- result = 31 * result + sdk
- return result
- }
- }
-
- public actual companion object {
- internal actual val logger = MiraiLogger.Factory.create(DeviceInfo::class, "DeviceInfo")
-
- /**
- * 生成随机 [DeviceInfo]
- *
- * @see DeviceInfoBuilder
- * @since 2.0
- */
- public actual fun random(): DeviceInfo = random(Random.Default)
-
- /**
- * 使用特定随机数生成器生成 [DeviceInfo]
- *
- * @see DeviceInfoBuilder
- * @since 2.9
- */
- public actual fun random(random: Random): DeviceInfo {
- return DeviceInfoCommonImpl.randomDeviceInfo(random)
- }
-
- /**
- * 将此 [DeviceInfo] 序列化为字符串. 序列化的字符串可以在以后通过 [DeviceInfo.deserializeFromString] 反序列化为 [DeviceInfo].
- *
- * 序列化的字符串有兼容性保证, 在旧版 mirai 序列化的字符串, 可以在新版 mirai 使用. 但新版 mirai 序列化的字符串不一定能在旧版使用.
- *
- * @since 2.15
- */
- public actual fun serializeToString(deviceInfo: DeviceInfo): String = DeviceInfoManager.serialize(deviceInfo)
-
- /**
- * 将通过 [serializeToString] 序列化得到的字符串反序列化为 [DeviceInfo].
- * 此函数兼容旧版 mirai 序列化的字符串.
- * @since 2.15
- */
- public actual fun deserializeFromString(string: String): DeviceInfo = DeviceInfoManager.deserialize(string)
- }
-
- /**
- * @since 2.9
- */
- @Suppress("DuplicatedCode")
- actual override fun equals(other: Any?): Boolean {
- return DeviceInfoCommonImpl.equalsImpl(this, other)
- }
-
-
- /**
- * @since 2.9
- */
- actual override fun hashCode(): Int {
- return DeviceInfoCommonImpl.hashCodeImpl(this)
- }
-}
diff --git a/mirai-core-api/src/nativeMain/kotlin/utils/ExternalResource.kt b/mirai-core-api/src/nativeMain/kotlin/utils/ExternalResource.kt
deleted file mode 100644
index 07be744f9..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/utils/ExternalResource.kt
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import io.ktor.utils.io.core.*
-import kotlinx.coroutines.CompletableDeferred
-import kotlinx.coroutines.Deferred
-import net.mamoe.mirai.contact.Contact
-import net.mamoe.mirai.contact.Contact.Companion.sendImage
-import net.mamoe.mirai.contact.Contact.Companion.uploadImage
-import net.mamoe.mirai.internal.utils.*
-import net.mamoe.mirai.message.MessageReceipt
-import net.mamoe.mirai.message.data.Image
-import net.mamoe.mirai.message.data.sendTo
-import net.mamoe.mirai.utils.ExternalResource.Companion.sendAsImageTo
-import net.mamoe.mirai.utils.ExternalResource.Companion.toExternalResource
-import net.mamoe.mirai.utils.ExternalResource.Companion.uploadAsImage
-
-/**
- * 一个*不可变的*外部资源. 仅包含资源内容, 大小, 文件类型, 校验值而不包含文件名, 文件位置等. 外部资源有可能是一个文件, 也有可能只存在于内存, 或者以任意其他方式实现.
- *
- * [ExternalResource] 在创建之后就应该保持其属性的不变, 即任何时候获取其属性都应该得到相同结果, 任何时候打开流都得到的一样的数据.
- *
- * # 创建
- * - [ByteArray.toExternalResource]
- *
- * ## 在 Kotlin 获得和使用 [ExternalResource] 实例
- *
- * ```
- * file.toExternalResource().use { resource -> // 安全地使用资源
- * contact.uploadImage(resource) // 用来上传图片
- * contact.files.uploadNewFile("/foo/test.txt", file) // 或者用来上传文件
- * }
- * ```
- *
- * 注意, 若使用 [Input], 必须手动关闭 [Input]. 一种使用情况示例:
- *
- * ```
- * inputStream.use { input -> // 安全地使用 InputStream
- * input.toExternalResource().use { resource -> // 安全地使用资源
- * contact.uploadImage(resource) // 用来上传图片
- * contact.files.uploadNewFile("/foo/test.txt", file) // 或者用来上传文件
- * }
- * }
- * ```
- *
- * ## 在 Java 获得和使用 [ExternalResource] 实例
- *
- * ```
- * try (ExternalResource resource = ExternalResource.create(file)) { // 使用文件 file
- * contact.uploadImage(resource); // 用来上传图片
- * contact.files.uploadNewFile("/foo/test.txt", file); // 或者用来上传文件
- * }
- * ```
- *
- * 注意, 若使用 [Input], 必须手动关闭 [Input]. 一种使用情况示例:
- *
- * ```java
- * try (InputStream stream = ...) { // 安全地使用 InputStream
- * try (ExternalResource resource = ExternalResource.create(stream)) { // 安全地使用资源
- * contact.uploadImage(resource); // 用来上传图片
- * contact.files.uploadNewFile("/foo/test.txt", file); // 或者用来上传文件
- * }
- * }
- * ```
- *
- * # 释放
- *
- * 当 [ExternalResource] 创建时就可能会打开一些资源.
- * 类似于 [Input], [ExternalResource] 需要被 [关闭][close].
- *
- * ## 未释放资源的补救策略
- *
- * 自 2.7 起, 每个 mirai 内置的 [ExternalResource] 实现都有引用跟踪, 当 [ExternalResource] 被 GC 后会执行被动释放.
- * 这依赖于 JVM 垃圾收集策略, 因此不可靠, 资源仍然需要手动 close.
- *
- * ## 使用单次自动释放
- *
- * 若创建的资源仅需要*很快地*使用一次, 可使用 [toAutoCloseable] 获得在使用一次后就会自动关闭的资源.
- *
- * 示例:
- * ```java
- * contact.uploadImage(ExternalResource.create(file).toAutoCloseable()); // 创建并立即使用单次自动释放的资源
- * ```
- *
- * **注意**: 如果仅使用 [toAutoCloseable] 而不通过 [Contact.uploadImage] 等 mirai 内置方法使用资源, 资源仍然会处于打开状态且不会被自动关闭.
- * 最终资源会由上述*未释放资源的补救策略*关闭, 但这依赖于 JVM 垃圾收集策略而不可靠.
- * 因此建议在创建单次自动释放的资源后就尽快使用它, 否则仍然需要考虑在正确的时间及时关闭资源.
- *
- * # 实现 [ExternalResource]
- *
- * 可以自行实现 [ExternalResource]. 但通常上述创建方法已足够使用.
- *
- * 建议继承 [AbstractExternalResource], 这将支持上文提到的资源自动释放功能.
- *
- * 实现时需保持 [ExternalResource] 在构造后就不可变, 并且所有属性都总是返回一个固定值.
- *
- * @see ExternalResource.uploadAsImage 将资源作为图片上传, 得到 [Image]
- * @see ExternalResource.sendAsImageTo 将资源作为图片发送
- * @see Contact.uploadImage 上传一个资源作为图片, 得到 [Image]
- * @see Contact.sendImage 发送一个资源作为图片
- *
- * @see FileCacheStrategy
- */
-public actual interface ExternalResource : Closeable {
-
- /**
- * 是否在 _使用一次_ 后自动 [close].
- *
- * 该属性仅供调用方参考. 如 [Contact.uploadImage] 会在方法结束时关闭 [isAutoClose] 为 `true` 的 [ExternalResource], 无论上传图片是否成功.
- *
- * 所有 mirai 内置的上传图片, 上传语音等方法都支持该行为.
- *
- * @since 2.8
- */
- public actual val isAutoClose: Boolean
- get() = false
-
- /**
- * 文件内容 MD5. 16 bytes
- */
- public actual val md5: ByteArray
-
- /**
- * 文件内容 SHA1. 16 bytes
- * @since 2.5
- */
- public actual val sha1: ByteArray
- get() =
- throw UnsupportedOperationException("ExternalResource.sha1 is not implemented by ${this::class.simpleName}")
- // 如果你要实现 [ExternalResource], 你也应该实现 [sha1].
- // 这里默认抛出 [UnsupportedOperationException] 是为了 (姑且) 兼容 2.5 以前的版本的实现.
-
-
- /**
- * 文件格式,如 "png", "amr". 当无法自动识别格式时为 [DEFAULT_FORMAT_NAME].
- *
- * 默认会从文件头识别, 支持的文件类型:
- * png, jpg, gif, tif, bmp, amr, silk
- *
- * @see net.mamoe.mirai.utils.getFileType
- * @see net.mamoe.mirai.utils.FILE_TYPES
- * @see DEFAULT_FORMAT_NAME
- */
- public actual val formatName: String
-
- /**
- * 文件大小 bytes
- */
- public actual val size: Long
-
- /**
- * 当 [close] 时会 [CompletableDeferred.complete] 的 [Deferred].
- */
- public actual val closed: Deferred
-
- /**
- * 打开 [Input]. 在返回的 [Input] 被 [关闭][Input.close] 前无法再次打开流.
- *
- * 关闭此流不会关闭 [ExternalResource].
- * @throws IllegalStateException 当上一个流未关闭又尝试打开新的流时抛出
- *
- * @since 2.13
- */
- @MiraiInternalApi
- public actual fun input(): Input
-
- @MiraiInternalApi
- public actual fun calculateResourceId(): String {
- return generateImageId(md5, formatName.ifEmpty { DEFAULT_FORMAT_NAME })
- }
-
- /**
- * 该 [ExternalResource] 的数据来源, 可能有以下的返回
- *
- * - [ByteArray] RAM
- * - ...
- *
- * implementation note:
- *
- * - 对于无法二次读取的数据来源 (如 [Input]), 返回 `null`
- * - 不要返回 [String], 没有约定 [String] 代表什么
- * - 数据源外漏会严重影响 [inputStream] 等的执行的可以返回 `null` (如文件句柄)
- *
- * @since 2.8.0
- */
- public actual val origin: Any? get() = null
-
- /**
- * 创建一个在 _使用一次_ 后就会自动 [close] 的 [ExternalResource].
- *
- * @since 2.8.0
- */
- public actual fun toAutoCloseable(): ExternalResource {
- return if (isAutoClose) this else {
- val delegate = this
- object : ExternalResource by delegate {
- override val isAutoClose: Boolean get() = true
- override fun toString(): String = "ExternalResourceWithAutoClose(delegate=$delegate)"
- override fun toAutoCloseable(): ExternalResource {
- return this
- }
- }
- }
- }
-
-
- public actual companion object {
- /**
- * 在无法识别文件格式时使用的默认格式名. "mirai".
- *
- * @see ExternalResource.formatName
- */
- public actual const val DEFAULT_FORMAT_NAME: String = "mirai"
-
- ///////////////////////////////////////////////////////////////////////////
- // region toExternalResource
- ///////////////////////////////////////////////////////////////////////////
-
- /**
- * 创建 [ExternalResource]. 注意, 返回的 [ExternalResource] 需要在使用完毕后调用 [ExternalResource.close] 关闭.
- *
- * @param formatName 查看 [ExternalResource.formatName]
- */
- public actual fun ByteArray.toExternalResource(formatName: String?): ExternalResource =
- ExternalResourceImplByByteArray(this, formatName)
-
- // endregion
-
- ///////////////////////////////////////////////////////////////////////////
- // region sendAsImageTo
- ///////////////////////////////////////////////////////////////////////////
-
- /**
- * 将图片作为单独的消息发送给指定联系人.
- *
- * **注意**:本函数不会关闭 [ExternalResource].
- *
- * @see Contact.uploadImage 上传图片
- * @see Contact.sendMessage 最终调用, 发送消息.
- *
- * @throws OverFileSizeMaxException
- */
- public actual suspend fun ExternalResource.sendAsImageTo(contact: C): MessageReceipt =
- contact.uploadImage(this).sendTo(contact)
-
- // endregion
-
- ///////////////////////////////////////////////////////////////////////////
- // region uploadAsImage
- ///////////////////////////////////////////////////////////////////////////
-
- /**
- * 上传图片并构造 [Image]. 这个函数可能需消耗一段时间.
- *
- * **注意**:本函数不会关闭 [ExternalResource].
- *
- * @param contact 图片上传对象. 由于好友图片与群图片不通用, 上传时必须提供目标联系人.
- *
- * @see Contact.uploadImage 最终调用, 上传图片.
- */
- public actual suspend fun ExternalResource.uploadAsImage(contact: Contact): Image = contact.uploadImage(this)
-
- // endregion
- }
-}
diff --git a/mirai-core-api/src/nativeMain/kotlin/utils/FileCacheStrategy.kt b/mirai-core-api/src/nativeMain/kotlin/utils/FileCacheStrategy.kt
deleted file mode 100644
index a94ae52f0..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/utils/FileCacheStrategy.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-/**
- * 资源缓存策略.
- *
- * 注意: 本接口只用于 JVM 平台. 在 native 平台没有作用.
- *
- * 由于上传资源时服务器要求提前给出 MD5 和文件大小等数据, 一些资源如 [InputStream] 需要首先缓存才能使用.
- *
- * 资源的缓存都是将 [InputStream] 缓存未 [ExternalResource]. 根据 [FileCacheStrategy] 实现不同, 可以以临时文件存储, 也可以在数据库或是内存按需存储.
- * Mirai 内置的实现有 [内存存储][MemoryCache] 和 [临时文件存储][TempCache].
- * 操作 [ExternalResource.toExternalResource] 时将会使用 [IMirai.FileCacheStrategy]. 可以覆盖, 示例:
- * ```
- * // Kotlin
- * Mirai.FileCacheStrategy = FileCacheStrategy.TempCache() // 使用系统默认缓存路径, 也是默认的行为
- * Mirai.FileCacheStrategy = FileCacheStrategy.TempCache(File("C:/cache")) // 使用自定义缓存路径
- *
- * // Java
- * Mirai.getInstance().setFileCacheStrategy(new FileCacheStrategy.TempCache()); // 使用系统默认缓存路径, 也是默认的行为
- * Mirai.getInstance().setFileCacheStrategy(new FileCacheStrategy.TempCache(new File("C:/cache"))); // 使用自定义的缓存路径
- * ```
- *
- * 此接口的实现和使用都是稳定的. 自行实现的 [FileCacheStrategy] 也可以被 Mirai 使用.
- *
- * 注意, 此接口目前仅缓存 [InputStream] 等一次性数据. 好友列表等数据由每个 [Bot] 的 [BotConfiguration.cacheDir] 缓存.
- *
- * ### 使用 [FileCacheStrategy] 的操作
- * - [ExternalResource.toExternalResource]
- * - [ExternalResource.uploadAsImage]
- * - [ExternalResource.sendAsImageTo]
- *
- * @see ExternalResource
- */
-public actual interface FileCacheStrategy {
- public actual companion object {
- /**
- * 当前平台下默认的缓存策略. 注意, 这可能不是 Mirai 全局默认使用的, Mirai 从 [IMirai.FileCacheStrategy] 获取.
- *
- * @see IMirai.FileCacheStrategy
- */
- @MiraiExperimentalApi
- public actual val PlatformDefault: FileCacheStrategy = object : FileCacheStrategy {}
- }
-}
\ No newline at end of file
diff --git a/mirai-core-api/src/nativeMain/kotlin/utils/LoginSolver.kt b/mirai-core-api/src/nativeMain/kotlin/utils/LoginSolver.kt
deleted file mode 100644
index 675352e71..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/utils/LoginSolver.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-internal actual object PlatformLoginSolverImplementations {
- actual val isSliderCaptchaSupported: Boolean get() = false
- actual val default: LoginSolver? get() = null
-}
\ No newline at end of file
diff --git a/mirai-core-api/src/nativeMain/kotlin/utils/MiraiLogger.kt b/mirai-core-api/src/nativeMain/kotlin/utils/MiraiLogger.kt
deleted file mode 100644
index d4af23e41..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/utils/MiraiLogger.kt
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import kotlin.reflect.KClass
-
-/**
- * 日志记录器.
- *
- * ## Mirai 日志系统
- *
- * Mirai 内建简单的日志系统, 即 [MiraiLogger]. [MiraiLogger] 的实现有 [SimpleLogger], [PlatformLogger], [SilentLogger].
- *
- * ## 实现或使用 [MiraiLogger]
- *
- * 不建议实现或使用 [MiraiLogger]. 请优先考虑使用上述第三方框架. [MiraiLogger] 仅应用于兼容旧版本代码.
- *
- * @see SimpleLogger 简易 logger, 它将所有的日志记录操作都转移给 lambda `(String?, Throwable?) -> Unit`
- * @see PlatformLogger 各个平台下的默认日志记录实现.
- * @see SilentLogger 忽略任何日志记录操作的 logger 实例.
- *
- * @see MiraiLoggerPlatformBase 平台通用基础实现. 若 Mirai 自带的日志系统无法满足需求, 请继承这个类并实现其抽象函数.
- */
-public actual interface MiraiLogger {
- /**
- * 可以 service 实现的方式覆盖.
- *
- * @since 2.7
- */
- public actual interface Factory {
- /**
- * 创建 [MiraiLogger] 实例.
- *
- * @param requester 请求创建 [MiraiLogger] 的对象的 class
- * @param identity 对象标记 (备注)
- */
- public actual fun create(requester: KClass<*>, identity: String?): MiraiLogger {
- return create(requester)
- }
-
- /**
- * 创建 [MiraiLogger] 实例.
- *
- * @param requester 请求创建 [MiraiLogger] 的对象
- */
- public actual fun create(requester: KClass<*>): MiraiLogger {
- throw UnsupportedOperationException() // Cannot be abstract since on JVM it is open
- }
-
- public actual companion object INSTANCE : Factory by loadService(Factory::class, fallbackImplementation = {
- @OptIn(MiraiInternalApi::class)
- object : Factory {
- override fun create(requester: KClass<*>): MiraiLogger {
- return PlatformLogger(requester.simpleName ?: requester.qualifiedName)
- }
-
- override fun create(requester: KClass<*>, identity: String?): MiraiLogger {
- return PlatformLogger(identity ?: requester.simpleName ?: requester.qualifiedName)
- }
- }
- })
- }
-
- public actual companion object;
-
- /**
- * 日志的标记. 在 Mirai 中, identity 可为
- * - "Bot"
- * - "BotNetworkHandler"
- * 等.
- *
- * 它只用于帮助调试或统计. 十分建议清晰定义 identity
- */
- public actual val identity: String?
-
- /**
- * 获取 [MiraiLogger] 是否已开启
- *
- * 除 [MiraiLoggerWithSwitch] 可控制开关外, 其他的所有 [MiraiLogger] 均一直开启.
- */
- public actual val isEnabled: Boolean
-
- /**
- * 当 VERBOSE 级别的日志启用时返回 `true`.
- *
- * 若 [isEnabled] 为 `false`, 返回 `false`.
- * 其他情况下返回 [isEnabled] 的值.
- *
- * @since 2.7
- */
- public actual val isVerboseEnabled: Boolean get() = isEnabled
-
- /**
- * 当 DEBUG 级别的日志启用时返回 `true`
- *
- * 若 [isEnabled] 为 `false`, 返回 `false`.
- * 其他情况下返回 [isEnabled] 的值.
- *
- * @since 2.7
- */
- public actual val isDebugEnabled: Boolean get() = isEnabled
-
- /**
- * 当 INFO 级别的日志启用时返回 `true`
- *
- * 若 [isEnabled] 为 `false`, 返回 `false`.
- * 其他情况下返回 [isEnabled] 的值.
- *
- * @since 2.7
- */
- public actual val isInfoEnabled: Boolean get() = isEnabled
-
- /**
- * 当 WARNING 级别的日志启用时返回 `true`
- *
- * 若 [isEnabled] 为 `false`, 返回 `false`.
- * 其他情况下返回 [isEnabled] 的值.
- *
- * @since 2.7
- */
- public actual val isWarningEnabled: Boolean get() = isEnabled
-
- /**
- * 当 ERROR 级别的日志启用时返回 `true`
- *
- * 若 [isEnabled] 为 `false`, 返回 `false`.
- * 其他情况下返回 [isEnabled] 的值.
- *
- * @since 2.7
- */
- public actual val isErrorEnabled: Boolean get() = isEnabled
-
- /**
- * 记录一个 `verbose` 级别的日志.
- * 无关紧要的, 经常大量输出的日志应使用它.
- */
- public actual fun verbose(message: String?)
-
- public actual fun verbose(e: Throwable?): Unit = verbose(null, e)
- public actual fun verbose(message: String?, e: Throwable?)
-
- /**
- * 记录一个 _调试_ 级别的日志.
- */
- public actual fun debug(message: String?)
-
- public actual fun debug(e: Throwable?): Unit = debug(null, e)
- public actual fun debug(message: String?, e: Throwable?)
-
-
- /**
- * 记录一个 _信息_ 级别的日志.
- */
- public actual fun info(message: String?)
-
- public actual fun info(e: Throwable?): Unit = info(null, e)
- public actual fun info(message: String?, e: Throwable?)
-
-
- /**
- * 记录一个 _警告_ 级别的日志.
- */
- public actual fun warning(message: String?)
-
- public actual fun warning(e: Throwable?): Unit = warning(null, e)
- public actual fun warning(message: String?, e: Throwable?)
-
-
- /**
- * 记录一个 _错误_ 级别的日志.
- */
- public actual fun error(message: String?)
-
- public actual fun error(e: Throwable?): Unit = error(null, e)
- public actual fun error(message: String?, e: Throwable?)
-
- /** 根据优先级调用对应函数 */
- public actual fun call(priority: SimpleLogger.LogPriority, message: String?, e: Throwable?): Unit =
- @OptIn(MiraiExperimentalApi::class)
- priority.correspondingFunction(this, message, e)
-}
diff --git a/mirai-core-api/src/nativeMain/kotlin/utils/PlatformLogger.kt b/mirai-core-api/src/nativeMain/kotlin/utils/PlatformLogger.kt
deleted file mode 100644
index d950a33e4..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/utils/PlatformLogger.kt
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import net.mamoe.mirai.internal.utils.StdoutLogger
-
-/**
- * 当前平台的默认的日志记录器.
- * - 在 _JVM 控制台_ 端的实现为 [println]
- * - 在 _Android_ 端的实现为 `android.util.Log`
- *
- *
- * 单条日志格式 (正则) 为:
- * ```regex
- * ^([\w-]*\s[\w:]*)\s(\w)\/(.*?):\s(.+)$
- * ```
- * 其中 group 分别为: 日期与时间, 严重程度, [identity], 消息内容.
- *
- * 示例:
- * ```log
- * 2020-05-21 19:51:09 V/Bot 123456789: Send: OidbSvc.0x88d_7
- * ```
- *
- * 日期时间格式为 `yyyy-MM-dd HH:mm:ss`,
- *
- * 严重程度为 V, I, W, E. 分别对应 verbose, info, warning, error
- *
- * @see MiraiLogger.create
- */
-@MiraiInternalApi
-public actual open class PlatformLogger actual constructor(identity: String?) :
- MiraiLoggerPlatformBase(), MiraiLogger {
-
- private val delegate = StdoutLogger(identity)
-
- override val identity: String? get() = delegate.identity
- override val isEnabled: Boolean get() = delegate.isEnabled
- override val isVerboseEnabled: Boolean get() = delegate.isVerboseEnabled
- override val isDebugEnabled: Boolean get() = delegate.isDebugEnabled
- override val isInfoEnabled: Boolean get() = delegate.isInfoEnabled
- override val isWarningEnabled: Boolean get() = delegate.isWarningEnabled
- override val isErrorEnabled: Boolean get() = delegate.isErrorEnabled
-
- override fun verbose0(message: String?, e: Throwable?) {
- delegate.verbose0(message, e)
- }
-
- override fun debug0(message: String?, e: Throwable?) {
- delegate.debug(message, e)
- }
-
- override fun info0(message: String?, e: Throwable?) {
- delegate.info0(message, e)
- }
-
- override fun warning0(message: String?, e: Throwable?) {
- delegate.warning(message, e)
- }
-
- override fun error0(message: String?, e: Throwable?) {
- delegate.error0(message, e)
- }
-}
\ No newline at end of file
diff --git a/mirai-core-api/src/nativeMain/kotlin/utils/Streamable.kt b/mirai-core-api/src/nativeMain/kotlin/utils/Streamable.kt
deleted file mode 100644
index a726cbab1..000000000
--- a/mirai-core-api/src/nativeMain/kotlin/utils/Streamable.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.toList
-import net.mamoe.mirai.contact.announcement.Announcement
-import net.mamoe.mirai.contact.announcement.Announcements
-
-/**
- * 表示一个可以创建[数据流][Flow]的对象.
- *
- * 实现这个接口的对象可以看做为元素 [T] 的集合.
- * 例如 [Announcements] 可以看作是 [Announcement] 的集合,
- * 使用 [Announcements.asFlow] 可以获取到包含所有 [Announcement] 列表的 [Flow]
- * 在 JVM, 还可以使用 `Announcements.asStream` 可以获取到包含所有 [Announcement] 列表的 `Stream`.
- *
- * @since 2.13
- */
-public actual interface Streamable {
- /**
- * 创建一个能获取 [T] 的 [Flow].
- */
- public actual fun asFlow(): Flow
-
- /**
- * 获取所有 [T] 列表, 将全部 [T] 都加载后再返回.
- *
- * @return 此时刻的 [T] 只读列表.
- */
- public actual suspend fun toList(): List = asFlow().toList()
-}
\ No newline at end of file
diff --git a/mirai-core-utils/build.gradle.kts b/mirai-core-utils/build.gradle.kts
index b53a79a9c..25d82759a 100644
--- a/mirai-core-utils/build.gradle.kts
+++ b/mirai-core-utils/build.gradle.kts
@@ -28,7 +28,6 @@ kotlin {
apply(plugin = "explicit-api")
configureJvmTargetsHierarchical("net.mamoe.mirai.utils")
- configureNativeTargetsHierarchical(project)
sourceSets {
val commonMain by getting {
@@ -42,15 +41,6 @@ kotlin {
relocateImplementation(`ktor-io_relocated`)
}
}
- configure(NATIVE_TARGETS.map { getByName(it + "Main") }
- + NATIVE_TARGETS.map { getByName(it + "Test") }) {
- dependencies {
- // no relocation in native
- implementation(`ktor-io`) {
- exclude(ExcludeProperties.`slf4j-api`)
- }
- }
- }
val commonTest by getting {
dependencies {
@@ -81,12 +71,6 @@ kotlin {
runtimeOnly(files("build/classes/kotlin/jvm/test")) // classpath is not properly set by IDE
}
}
-
- findByName("nativeMain")?.apply {
- dependencies {
-// implementation("com.soywiz.korlibs.krypto:krypto:2.4.12") // ':mirai-core-utils:compileNativeMainKotlinMetadata' fails because compiler cannot find reference
- }
- }
}
}
diff --git a/mirai-core-utils/src/mingwX64Main/kotlin/MiraiFileImpl.kt b/mirai-core-utils/src/mingwX64Main/kotlin/MiraiFileImpl.kt
deleted file mode 100644
index da57e46e3..000000000
--- a/mirai-core-utils/src/mingwX64Main/kotlin/MiraiFileImpl.kt
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import io.ktor.utils.io.bits.*
-import io.ktor.utils.io.core.*
-import io.ktor.utils.io.errors.*
-import kotlinx.cinterop.*
-import platform.posix.*
-import platform.windows.*
-
-private fun getFullPathName(path: String): String = memScoped {
- ShortArray(MAX_PATH).usePinned { pin ->
- val len = GetFullPathNameW(path, MAX_PATH, pin.addressOf(0).reinterpret(), null).toInt()
- if (len != 0) {
- return pin.get().toKStringFromUtf16(len)
- } else {
- when (val errno = errno) {
- ENOTDIR -> return@memScoped path
- EACCES -> return@memScoped path // permission denied
- ENOENT -> return@memScoped path // no such file
- else -> throw IllegalArgumentException(
- "Invalid path($errno): $path",
- cause = PosixException.forErrno(posixFunctionName = "GetFullPathNameW()")
- )
- }
- }
- }
-}
-
-private fun ShortArray.toKStringFromUtf16(len: Int): String {
- val chars = CharArray(len)
- var index = 0
- while (index < len) {
- chars[index] = this[index].toInt().toChar()
- ++index
- }
- return chars.concatToString()
-}
-
-internal actual class MiraiFileImpl actual constructor(
- // canonical
- path: String
-) : MiraiFile {
- override val path = path.replace("/", "\\")
-
- actual companion object {
- private val ROOT_REGEX = Regex("""^([a-zA-z]+:[/\\])""")
- private const val SEPARATOR = '\\'
-
- @Suppress("UnnecessaryOptInAnnotation")
- @OptIn(UnsafeNumber::class)
- actual fun getWorkingDir(): MiraiFile {
- val path = memScoped {
- ByteArray(PATH_MAX).usePinned {
- getcwd(it.addressOf(0), it.get().size.convert())
- it.get().toKString()
- }
- }
- return MiraiFile.create(path)
- }
- }
-
- override val absolutePath: String by lazy {
- val result = ROOT_REGEX.matchEntire(this.path)
- ?: return@lazy getFullPathName(this.path).removeSuffix(SEPARATOR.toString())
- return@lazy result.groups.first()!!.value
- }
-
- private fun Char.isSeparator() = this == '/' || this == '\\'
-
- override val parent: MiraiFile? by lazy {
- if (ROOT_REGEX.matchEntire(this.path) != null) return@lazy null
- val absolute = absolutePath
- val p = absolute.substringBeforeLast(SEPARATOR, "")
- if (p.isEmpty()) {
- return@lazy null
- }
- if (p.lastOrNull() == ':') {
- if (absolute.lastIndexOf(SEPARATOR) == p.lastIndex) {
- // file is C:/
- return@lazy null
- } else {
- return@lazy MiraiFileImpl("$p/") // file is C:/xxx
- }
- }
- MiraiFileImpl(p)
- }
-
- override val name: String
- get() = if (absolutePath.matches(ROOT_REGEX)) absolutePath
- else absolutePath.substringAfterLast(SEPARATOR)
-
- init {
- checkName(absolutePath.substringAfterLast(SEPARATOR)) // do not check drive letter
- }
-
- private fun checkName(name: String) {
- name.substringAfterLast(SEPARATOR).forEach { c ->
- if (c in """\/:?*"><|""") {
- throw IllegalArgumentException("'${name}' contains illegal character '$c'.")
- }
- }
-
-// memScoped {
-// val b = alloc()
-// CheckNameLegalDOS8Dot3A(absolutePath, nullPtr(), 0, nullPtr(), b.ptr)
-// if (b.value != 1) {
-// throw IllegalArgumentException("'${name}' contains illegal character.")
-// }
-// }
- }
-
- override val length: Long
- get() = useStat { it.st_size.convert() } ?: 0
-// memScoped {
-// val handle = CreateFileW(
-// absolutePath,
-// GENERIC_READ,
-// FILE_SHARE_READ,
-// null,
-// OPEN_EXISTING,
-// FILE_ATTRIBUTE_NORMAL,
-// null
-// ) ?: return@memScoped 0
-// val length = alloc()
-// if (GetFileSize(handle, length.ptr) == INVALID_FILE_SIZE) {
-// if (GetLastError() == NO_ERROR.toUInt()) {
-// return INVALID_FILE_SIZE.convert()
-// }
-// throw PosixException.forErrno(posixFunctionName = "GetFileSize()").wrapIO()
-// }
-// if (CloseHandle(handle) == FALSE) {
-// throw PosixException.forErrno(posixFunctionName = "CloseHandle()").wrapIO()
-// }
-// length.value.convert()
-// }
-
-
- override val isFile: Boolean
- get() = useStat { it.st_mode.convert() flag S_IFREG } ?: false
-
- override val isDirectory: Boolean
- get() = useStat { it.st_mode.convert() flag S_IFDIR } ?: false
-
- override fun exists(): Boolean = getFileAttributes() != INVALID_FILE_ATTRIBUTES
-
- private fun getFileAttributes(): DWORD = memScoped { GetFileAttributesW(absolutePath) }
-
- override fun resolve(path: String): MiraiFile {
- when (path) {
- "." -> return this
- ".." -> return parent ?: this // root
- }
-
- if (ROOT_REGEX.find(path) != null) { // absolute
- return MiraiFileImpl(path)
- }
-
- return MiraiFileImpl(this.absolutePath + SEPARATOR + path) // assuming path is 'appendable'
- }
-
- override fun resolve(file: MiraiFile): MiraiFile {
- val parent = file.parent ?: return resolve(file.name)
- return resolve(parent).resolve(file.name)
- }
-
- override fun createNewFile(): Boolean {
- // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
- val handle = CreateFileW(
- absolutePath,
- GENERIC_READ,
- FILE_SHARE_DELETE,
- null,
- CREATE_NEW,
- FILE_ATTRIBUTE_NORMAL,
- null
- )
- if (handle == null || handle == INVALID_HANDLE_VALUE) {
- return false
- }
- if (CloseHandle(handle) == FALSE) {
- throw PosixException.forErrno(posixFunctionName = "CloseHandle()").wrapIO()
- }
- return true
- }
-
- override fun delete(): Boolean {
- return if (isFile) {
- DeleteFileW(absolutePath) != 0
- } else {
- RemoveDirectoryW(absolutePath) != 0
- }
- }
-
- override fun mkdir(): Boolean {
- memScoped {
- val v = alloc<_SECURITY_ATTRIBUTES>()
- return CreateDirectoryW(absolutePath, v.ptr) != 0
- }
- }
-
- override fun mkdirs(): Boolean {
- this.parent?.mkdirs()
- return mkdir()
- }
-
- override fun input(): Input {
-// println(absolutePath)
-// val handle2 = fopen(absolutePath, "rb") ?:throw IOException(
-// "Failed to open file '$absolutePath'",
-// PosixException.forErrno(posixFunctionName = "fopen()")
-// )
-// return PosixInputForFile(handle2)
- // Will get I/O operation failed due to posix error code 2
-
- val handle = CreateFileW(
- absolutePath,
- GENERIC_READ,
- FILE_SHARE_DELETE,
- null,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- null
- )
- if (handle == null || handle == INVALID_HANDLE_VALUE) throw IOException(
- "Failed to open file '$absolutePath'",
- PosixException.forErrno(posixFunctionName = "CreateFileW()")
- )
- return WindowsFileInput(handle)
- }
-
- override fun output(): Output {
-// val handle2 = fopen(absolutePath, "wb")
-// ?: throw IOException(
-// "Failed to open file '$absolutePath'",
-// PosixException.forErrno(posixFunctionName = "fopen()")
-// )
-// return PosixFileInstanceOutput(handle)
-//
- val handle = CreateFileW(
- absolutePath,
- GENERIC_WRITE,
- FILE_SHARE_DELETE,
- null,
- (if (exists()) TRUNCATE_EXISTING else CREATE_NEW).toUInt(),
- FILE_ATTRIBUTE_NORMAL,
- null
- )
- if (handle == null || handle == INVALID_HANDLE_VALUE) throw IOException(
- "Failed to open file '$absolutePath'",
- PosixException.forErrno(posixFunctionName = "CreateFileW()")
- )
- return WindowsFileOutput(handle)
- }
-
- override fun hashCode(): Int {
- return this.path.hashCode()
- }
-
- override fun equals(other: Any?): Boolean {
- if (other == null) return false
- if (!isSameType(this, other)) return false
- return this.path == other.path
- }
-
- override fun toString(): String {
- return "MiraiFileImpl($path)"
- }
-}
-
-
-internal class WindowsFileInput(private val file: HANDLE) : Input() {
- private var closed = false
-
- override fun fill(destination: Memory, offset: Int, length: Int): Int {
- if (file == INVALID_HANDLE_VALUE) return 0
-
- memScoped {
- val n = alloc()
- if (ReadFile(file, destination.pointer + offset, length.convert(), n.ptr, null) == FALSE) {
- throw PosixException.forErrno(posixFunctionName = "ReadFile()").wrapIO()
- }
-
- return n.value.convert().toInt()
- }
- }
-
- override fun closeSource() {
- if (closed) return
- closed = true
-
- if (file != INVALID_HANDLE_VALUE) {
- if (CloseHandle(file) == FALSE) {
- throw PosixException.forErrno(posixFunctionName = "CloseHandle()").wrapIO()
- }
- }
- }
-}
-
-@Suppress("DEPRECATION")
-internal class WindowsFileOutput(private val file: HANDLE) : Output() {
- private var closed = false
-
- override fun flush(source: Memory, offset: Int, length: Int) {
- val end = offset + length
- var currentOffset = offset
-
- memScoped {
- val written = alloc()
- while (currentOffset < end) {
- val result = WriteFile(
- file,
- source.pointer + currentOffset.convert(),
- (end - currentOffset).convert(),
- written.ptr,
- null
- ).convert()
- if (result == FALSE) {
- throw PosixException.forErrno(posixFunctionName = "WriteFile()").wrapIO()
- }
- currentOffset += written.value.toInt()
- }
-
- }
- }
-
- override fun closeDestination() {
- if (closed) return
- closed = true
-
- if (CloseHandle(file) == FALSE) {
- throw PosixException.forErrno(posixFunctionName = "CloseHandle()").wrapIO()
- }
- }
-}
diff --git a/mirai-core-utils/src/mingwX64Main/kotlin/StandardUtils.kt b/mirai-core-utils/src/mingwX64Main/kotlin/StandardUtils.kt
deleted file mode 100644
index d7c86e5fc..000000000
--- a/mirai-core-utils/src/mingwX64Main/kotlin/StandardUtils.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import platform.windows.GetCurrentProcessorNumber
-
-
-public actual fun availableProcessors(): Int =
- GetCurrentProcessorNumber().toInt().coerceAtLeast(4) // somehow it worked on my machine but not on CI
\ No newline at end of file
diff --git a/mirai-core-utils/src/mingwX64Test/kotlin/MiraiFileImplTest.kt b/mirai-core-utils/src/mingwX64Test/kotlin/MiraiFileImplTest.kt
deleted file mode 100644
index 60db9642a..000000000
--- a/mirai-core-utils/src/mingwX64Test/kotlin/MiraiFileImplTest.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import kotlin.math.absoluteValue
-import kotlin.random.Random
-import kotlin.test.Test
-import kotlin.test.assertEquals
-
-internal class WindowsMiraiFileImplTest : AbstractNativeMiraiFileImplTest() {
- private val rand = Random.nextInt().absoluteValue
- override val baseTempDir: MiraiFile = MiraiFile.create("C:\\mirai_unit_tests")
- override val tempPath = "C:\\mirai_unit_tests\\temp$rand"
-
- @Test
- override fun parent() {
- assertEquals("C:\\mirai_unit_tests", tempDir.parent!!.absolutePath)
- super.parent()
- }
-
- @Test
- override fun `canonical paths for non-canonical input`() {
- super.`canonical paths for non-canonical input`()
-
- // extra /sss/..
- MiraiFile.create("$tempPath/sss/..").resolve("test").let {
- assertPathEquals("${tempPath}/test", it.path) // Windows resolves always
- assertPathEquals("${tempPath}/test", it.absolutePath)
- }
- }
-
- @Test
- override fun `resolve absolute`() {
- MiraiFile.create("$tempPath/").resolve("C:\\mirai_unit_tests").let {
- assertEquals("C:\\mirai_unit_tests", it.path)
- assertEquals("C:\\mirai_unit_tests", it.absolutePath)
- }
- }
-}
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeMain/kotlin/Base64.kt b/mirai-core-utils/src/nativeMain/kotlin/Base64.kt
deleted file mode 100644
index 2d9ba0af8..000000000
--- a/mirai-core-utils/src/nativeMain/kotlin/Base64.kt
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-@file:Suppress("RedundantVisibilityModifier")
-
-package net.mamoe.mirai.utils
-
-import io.ktor.utils.io.core.*
-
-public actual fun String.decodeBase64(): ByteArray {
- return Base64Impl.decode(this)
-}
-
-public actual fun ByteArray.encodeBase64(): String {
- return Base64Impl.encode(this)
-}
-
-/**
- * From .
- * @author EmilHernvall
- */
-private object Base64Impl {
- fun encode(data: ByteArray): String {
- val tbl = charArrayOf(
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
- 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
- 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
- )
- val buffer = StringBuilder()
- var pad = 0
- var i = 0
- while (i < data.size) {
- var b = data[i].toInt() and 0xFF shl 16 and 0xFFFFFF
- if (i + 1 < data.size) {
- b = b or (data[i + 1].toInt() and 0xFF shl 8)
- } else {
- pad++
- }
- if (i + 2 < data.size) {
- b = b or (data[i + 2].toInt() and 0xFF)
- } else {
- pad++
- }
- for (j in 0 until 4 - pad) {
- val c = b and 0xFC0000 shr 18
- buffer.append(tbl[c])
- b = b shl 6
- }
- i += 3
- }
- for (j in 0 until pad) {
- buffer.append("=")
- }
- return buffer.toString()
- }
-
- fun decode(data: String): ByteArray {
- val tbl = intArrayOf(
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2,
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30,
- 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
- )
- val bytes: ByteArray = data.toByteArray()
- return buildPacket {
- var i = 0
- while (i < bytes.size) {
- var b: Int
- b = if (tbl[bytes[i].toInt()] != -1) {
- tbl[bytes[i].toInt()] and 0xFF shl 18
- } else {
- i++
- continue
- }
- var num = 0
- if (i + 1 < bytes.size && tbl[bytes[i + 1].toInt()] != -1) {
- b = b or (tbl[bytes[i + 1].toInt()] and 0xFF shl 12)
- num++
- }
- if (i + 2 < bytes.size && tbl[bytes[i + 2].toInt()] != -1) {
- b = b or (tbl[bytes[i + 2].toInt()] and 0xFF shl 6)
- num++
- }
- if (i + 3 < bytes.size && tbl[bytes[i + 3].toInt()] != -1) {
- b = b or (tbl[bytes[i + 3].toInt()] and 0xFF)
- num++
- }
- while (num > 0) {
- val c = b and 0xFF0000 shr 16
- writeByte(c.toByte())
- b = b shl 8
- num--
- }
- i += 4
- }
- }.readBytes()
- }
-}
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeMain/kotlin/ByteArrayOp.kt b/mirai-core-utils/src/nativeMain/kotlin/ByteArrayOp.kt
deleted file mode 100644
index e923d95b8..000000000
--- a/mirai-core-utils/src/nativeMain/kotlin/ByteArrayOp.kt
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-@file:Suppress("RedundantVisibilityModifier")
-
-package net.mamoe.mirai.utils
-
-import io.ktor.utils.io.bits.*
-import io.ktor.utils.io.core.*
-import kotlinx.cinterop.*
-import platform.zlib.*
-
-
-public actual val DEFAULT_BUFFER_SIZE: Int get() = 8192
-
-public actual fun ByteArray.md5(offset: Int, length: Int): ByteArray {
- MD5.create().run {
- update(this@md5, offset, length)
- return digest().bytes
- }
-}
-
-public actual fun ByteArray.sha1(offset: Int, length: Int): ByteArray = SHA1.create().run {
- update(this@sha1, offset, length)
- return digest().bytes
-}
-
-public actual fun ByteArray.sha256(offset: Int, length: Int): ByteArray = SHA256.create().run {
- update(this@sha256, offset, length)
- return digest().bytes
-}
-
-/**
- * WARNING: DO NOT SET THIS BUFFER TOO SMALL, OR YOU WILL SEE COMPRESSION ERROR.
- */
-@set:TestOnly
-public var ZLIB_BUFFER_SIZE: Long = 8192
-
-public actual fun ByteArray.gzip(offset: Int, length: Int): ByteArray {
- return GzipCompressionInput(this.toReadPacket(offset, length)).use { it.readBytes() }
-}
-
-public actual fun ByteArray.ungzip(offset: Int, length: Int): ByteArray {
- return GzipDecompressionInput(this.toReadPacket(offset, length)).use { it.readBytes() }
-}
-
-public actual fun ByteArray.deflate(offset: Int, length: Int): ByteArray {
- return DeflateInput(this.toReadPacket(offset, length)).use { it.readBytes() }
-}
-
-public actual fun ByteArray.inflate(offset: Int, length: Int): ByteArray {
- return InflateInput(this.toReadPacket(offset, length)).use { it.readBytes() }
-}
-
-
-@Suppress("FunctionName")
-public fun GzipCompressionInput(source: Input): Input {
- return ZlibInput(
- source = source,
- zlibInit = { deflateInit2(it, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 or 16, 8, Z_DEFAULT_STRATEGY) },
- zlibProcess = { z, flush -> deflate(z, flush) },
- zlibHasPending = null,
- zlibFlushMode = { if (it) Z_FINISH else Z_NO_FLUSH },
- zlibEnd = { deflateEnd(it) },
- )
-}
-
-@Suppress("FunctionName")
-public actual fun GzipDecompressionInput(source: Input): Input {
- return ZlibInput(
- source = source,
- zlibInit = { inflateInit2(it, 15 or 16) },
- zlibProcess = { z, flush -> inflate(z, flush) },
- zlibHasPending = null,
- zlibFlushMode = { if (it) Z_SYNC_FLUSH else Z_NO_FLUSH },
- zlibEnd = { inflateEnd(it) },
- )
-}
-
-@Suppress("FunctionName")
-public actual fun InflateInput(source: Input): Input {
- return ZlibInput(
- source = source,
- zlibInit = { inflateInit2(it, 15) },
- zlibProcess = { z, flush -> inflate(z, flush) },
- zlibHasPending = null,
- zlibFlushMode = { if (it) Z_SYNC_FLUSH else Z_NO_FLUSH },
- zlibEnd = { inflateEnd(it) },
- )
-}
-
-@Suppress("FunctionName")
-public actual fun DeflateInput(source: Input): Input {
- return ZlibInput(
- source = source,
- zlibInit = { deflateInit(it, Z_DEFAULT_COMPRESSION) },
- zlibProcess = { z, flush -> deflate(z, flush) },
- zlibHasPending = { z ->
- memScoped {
- val pendingBytes = cValue().ptr
- val pendingBits = cValue().ptr
-
- if (deflatePending(z, pendingBytes, pendingBits) != Z_OK) {
- false
- } else {
- pendingBytes.pointed.value > 0u || pendingBits.pointed.value > 0
- }
- }
- },
- zlibFlushMode = { if (it) Z_FINISH else Z_NO_FLUSH },
- zlibEnd = { deflateEnd(it) },
- )
-}
-
-
-/**
- * Input will be closed.
- */
-public actual fun Input.gzipAllAvailable(): ByteArray {
- return GzipCompressionInput(this).use { it.readBytes() }
-}
-
-/**
- * Input will be closed.
- */
-public actual fun Input.ungzipAllAvailable(): ByteArray {
- return GzipDecompressionInput(this).use { it.readBytes() }
-}
-
-/**
- * Input will be closed.
- */
-public actual fun Input.inflateAllAvailable(): ByteArray {
- return InflateInput(this).use { it.readBytes() }
-}
-
-/**
- * Input will be closed.
- */
-public actual fun Input.deflateAllAvailable(): ByteArray {
- return DeflateInput(this).use { it.readBytes() }
-}
-
-
-/**
- * [source] will be closed on [ZlibInput.close]
- */
-internal class ZlibInput(
- private val source: Input,
- zlibInit: (z_streamp) -> Int,
- private val zlibProcess: (z_streamp, flush: Int) -> Int,
- private val zlibHasPending: ((z_streamp) -> Boolean)?, // null lambda means operation not defined
- private val zlibFlushMode: (shouldFlushAll: Boolean) -> Int,
- private val zlibEnd: (z_streamp) -> Int,
-) : Input() {
- private val z: z_stream = nativeHeap.alloc()
- // Zlib manual: https://refspecs.linuxbase.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/zlib-inflate-1.html
-
- init {
- val r = zlibInit(z.ptr)
- if (r != 0) {
- nativeHeap.free(z)
- error("Failed to init zlib: $r (${getZlibError(r)})")
- }
- }
-
- private var bufferReadableSize = 0L
- private val inputBuffer = nativeHeap.allocArray(ZLIB_BUFFER_SIZE)
-
- private var closed = false
-
- override fun close() {
- if (closed) return
- closed = true
- debug { "close" }
- super.close()
- debug { "freeing inputBuffer" }
- nativeHeap.free(inputBuffer)
- debug { "freed" }
- }
-
- override fun closeSource() {
- debug { "closeSource" }
- source.close()
- debug { "zlibEnd" }
- zlibEnd(z.ptr)
- debug { "zlibEnd done" }
- }
-
- override fun fill(destination: Memory, offset: Int, length: Int): Int {
- require(offset in 0..destination.size32) { "invalid offset: $offset" }
- require(length in 0..destination.size32) { "invalid length: $length" }
- require(offset + length in 0..destination.size32) { "invalid offset and length: $offset, $length" }
-
- debug { "prepare: bufferReadableSize = $bufferReadableSize" }
- debug { "prepare: previous value: z.avail_in=${z.avail_in}, z.avail_out=${z.avail_out}" }
-
- val filled = try {
- if (z.avail_in == 0u) {
-
- // These two cases are similar.
-// if (z.avail_out == 0u) {
-// // Last time we used all the output, there is either something cached in Zlib, or no further source.
-// } else {
-// // We did not use all the inputs, meaning least time we used all avail_in.
-// }
-
- // bot input and output are used
- val flush = updateAvailIn() ?: return 0
- copyOutputsFromZlib(destination, offset, length, flush)
- } else {
- // Inputs not used up.
- copyOutputsFromZlib(destination, offset, length, Z_NO_FLUSH)
- }
-
- } catch (e: Throwable) {
- // If you throw this error up, ktor will somehow kill the process. (Ktor 2.0.2)
- debug { e.printStackTrace(); "" }
- return 0
- }
- check(filled in 0..length) { "Filled more than $length bytes: $filled" }
- check(filled in 0..destination.size) { "Filled more than ${destination.size} bytes: $filled" }
- return filled
- }
-
- private fun copyOutputsFromZlib(memory: Memory, offset: Int, length: Int, flush: Int): Int {
- debug { "copyOutputsFromZlib, memory.offset = $offset, memory.length=$length, memory.size=${memory.size}" }
-
- z.avail_out = length.convert()
- z.next_out = (memory.pointer + offset)!!.reinterpret()
-
- // We still have input, no need to update.
- debug { "Set z.avail_out=${z.avail_out}, z.next_out=(memory.pointer + offset)!!.reinterpret()" }
- debug { "Calling zlib, flush = $flush" }
-
- val p = zlibProcess(z.ptr, flush)
- when (p) {
- Z_BUF_ERROR -> error("Zlib failed to process data. (Z_BUF_ERROR)")
- Z_MEM_ERROR -> throw OutOfMemoryError("Insufficient native heap memory for Zlib. (Z_MEM_ERROR)")
- Z_STREAM_ERROR -> error("Zlib failed to process data. (Z_STREAM_ERROR)")
- Z_DATA_ERROR -> error("Zlib failed to process data. (Z_DATA_ERROR)")
- Z_NEED_DICT -> error("Zlib failed to process data. (Z_NEED_DICT)")
- else -> debug { "zlib: $p" }
- }
- val readSize = (length.toUInt() - z.avail_out).toInt()
-
- debug { "Zlib produced readSize=$readSize bytes" }
-// debug { "Partial output: ${memory.readBytes(bufferReadableSize).toUHexString()}" }
- debug { "Now z.avail_in=${z.avail_in}, z.avail_out=${z.avail_out}" }
-
- if (p == Z_FINISH) {
- debug { "Zlib returned Z_FINISH. Ignoring result check." }
- return readSize
- }
-
- if (p == Z_STREAM_END) {
- debug { "Zlib returned Z_STREAM_END. Ignoring result check." }
- return readSize
- }
-
- if (bufferReadableSize == 0L && (z.avail_in == 0u && source.endOfInput)) {
- if (zlibHasPending?.invoke(z.ptr) == true) {
- // has pending. So the data must be incomplete.
- error("Failed to process data, possibly bad data inputted.")
-// if (z.avail_in == 0u && source.endOfInput) {
-// // no any input.
-// } else {
-// // there's some input, so we can still read.
-// }
- } else {
- // no pending, but we should expect Z_FINISH in this case.
- error("Zlib read 0 byte, but it should not happen.")
- }
- // can't read
- }
- return readSize
- }
-
- private fun updateAvailIn(): Int? {
- val read = source.readAvailable(inputBuffer, 0, ZLIB_BUFFER_SIZE)
- if (read == 0L) {
- debug { "updateAvailIn: endOfInput, closing" }
- close() // automatically close
- return null // no more source available
- }
- bufferReadableSize = read
- z.avail_in = read.toUInt()
- val flush = zlibFlushMode(read < ZLIB_BUFFER_SIZE || source.endOfInput)
- debug { "inputBuffer content: " + inputBuffer.readBytes(read.toInt()).toUHexString() }
- z.next_in = inputBuffer.reinterpret()
- debug { "Updated availIn: z.avail_in=${z.avail_in}, z.next_in = inputBuffer.reinterpret()" }
- return flush
- }
-
- private companion object {
- private fun getZlibError(it: Int): String {
- return when (it) {
- Z_DATA_ERROR -> "Z_DATA_ERROR"
- Z_STREAM_ERROR -> "Z_STREAM_ERROR"
- else -> "Unknown error $it"
- }
- }
-
-
- private const val debugging = false
- private inline fun debug(string: () -> String) {
- if (debugging) println(string())
- }
-
- private inline fun debug() {
- if (debugging) println()
- }
- }
-}
-
-
-//private fun ByteArray.callImpl(
-// fn: (CValuesRef, UInt, CValuesRef) -> Boolean,
-// offset: Int,
-// length: Int
-//): ByteArray {
-// checkOffsetAndLength(offset, length)
-//
-// memScoped {
-// val r = alloc()
-// if (!fn(toCValues().ptr.reinterpret().plus(offset)!!, length.toUInt(), r.ptr)) {
-// throw IllegalStateException("Failed platform implementation call")
-// }
-// try {
-// return r.arr?.readBytes(r.size.toInt())!!
-// } finally {
-// free(r.arr)
-// }
-// }
-//}
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeMain/kotlin/Clock.kt b/mirai-core-utils/src/nativeMain/kotlin/Clock.kt
deleted file mode 100644
index 5a15e11a4..000000000
--- a/mirai-core-utils/src/nativeMain/kotlin/Clock.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-@file:Suppress("RedundantVisibilityModifier")
-
-package net.mamoe.mirai.utils
-
-public actual inline fun measureTimeMillis(block: () -> Unit): Long {
- val start = currentTimeMillis() // getTimeMillis in stdlib doesn't work on some native targets.
- block()
- return currentTimeMillis() - start
-}
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeMain/kotlin/Closeable.kt b/mirai-core-utils/src/nativeMain/kotlin/Closeable.kt
deleted file mode 100644
index 2de8280bc..000000000
--- a/mirai-core-utils/src/nativeMain/kotlin/Closeable.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import io.ktor.utils.io.core.use as ktorUse
-
-public actual typealias Closeable = io.ktor.utils.io.core.Closeable
-
-@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
-@kotlin.internal.LowPriorityInOverloadResolution
-public actual inline fun C.use(block: (C) -> R): R = ktorUse(block)
-
-public actual fun Closeable.asKtorCloseable(): io.ktor.utils.io.core.Closeable = this
-public actual fun io.ktor.utils.io.core.Closeable.asMiraiCloseable(): Closeable = this
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeMain/kotlin/Collections.kt b/mirai-core-utils/src/nativeMain/kotlin/Collections.kt
deleted file mode 100644
index 1c2b70e2d..000000000
--- a/mirai-core-utils/src/nativeMain/kotlin/Collections.kt
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-@file:Suppress("RedundantVisibilityModifier")
-
-package net.mamoe.mirai.utils
-
-import kotlinx.atomicfu.locks.ReentrantLock
-import kotlinx.atomicfu.locks.reentrantLock
-import kotlinx.atomicfu.locks.withLock
-import kotlin.reflect.KClass
-
-@Suppress("FunctionName")
-public actual fun ConcurrentHashMap(): MutableMap {
- return LockedConcurrentHashMap(reentrantLock())
-}
-
-private class LockedConcurrentHashSet(
- private val lock: ReentrantLock,
- private val delegate: MutableSet = mutableSetOf()
-) : MutableSet {
- override fun add(element: E): Boolean = lock.withLock {
- return delegate.add(element)
- }
-
- override fun addAll(elements: Collection): Boolean = lock.withLock {
- return delegate.addAll(elements)
- }
-
- override val size: Int get() = lock.withLock { delegate.size }
-
- override fun clear() = lock.withLock { delegate.clear() }
-
- override fun isEmpty(): Boolean = lock.withLock { delegate.isEmpty() }
- override fun containsAll(elements: Collection): Boolean = lock.withLock { delegate.containsAll(elements) }
- override fun contains(element: E): Boolean = lock.withLock { delegate.contains(element) }
-
- override fun iterator(): MutableIterator = delegate.iterator() // no effect for locking
-
- @Suppress("ConvertArgumentToSet")
- override fun retainAll(elements: Collection): Boolean = lock.withLock { delegate.retainAll(elements) }
-
- @Suppress("ConvertArgumentToSet")
- override fun removeAll(elements: Collection): Boolean = lock.withLock { delegate.removeAll(elements) }
-
- override fun remove(element: E): Boolean = lock.withLock { delegate.remove(element) }
-
-
- override fun equals(other: Any?): Boolean = delegate == other
- override fun hashCode(): Int = delegate.hashCode()
- override fun toString(): String = delegate.toString()
-}
-
-private class LockedConcurrentCollection(
- private val lock: ReentrantLock,
- private val delegate: MutableCollection
-) : MutableCollection {
- override fun add(element: E): Boolean = lock.withLock {
- return delegate.add(element)
- }
-
- override fun addAll(elements: Collection): Boolean = lock.withLock {
- return delegate.addAll(elements)
- }
-
- override val size: Int get() = lock.withLock { delegate.size }
-
- override fun clear() = lock.withLock { delegate.clear() }
-
- override fun isEmpty(): Boolean = lock.withLock { delegate.isEmpty() }
- override fun containsAll(elements: Collection): Boolean = lock.withLock { delegate.containsAll(elements) }
- override fun contains(element: E): Boolean = lock.withLock { delegate.contains(element) }
-
- override fun iterator(): MutableIterator = delegate.iterator() // no effect for locking
-
- @Suppress("ConvertArgumentToSet")
- override fun retainAll(elements: Collection): Boolean = lock.withLock { delegate.retainAll(elements) }
-
- @Suppress("ConvertArgumentToSet")
- override fun removeAll(elements: Collection): Boolean = lock.withLock { delegate.removeAll(elements) }
-
- override fun remove(element: E): Boolean = lock.withLock { delegate.remove(element) }
-
- override fun equals(other: Any?): Boolean = delegate == other
- override fun hashCode(): Int = delegate.hashCode()
- override fun toString(): String = delegate.toString()
-}
-
-private class LockedConcurrentHashMap(
- private val lock: ReentrantLock,
- private val delegate: MutableMap = mutableMapOf()
-) : MutableMap {
- override val entries: MutableSet>
- get() = lock.withLock { LockedConcurrentHashSet(lock, delegate.entries) }
-
- override val keys: MutableSet get() = lock.withLock { LockedConcurrentHashSet(lock, delegate.keys) }
- override val size: Int get() = lock.withLock { delegate.size }
- override val values: MutableCollection
- get() = lock.withLock { LockedConcurrentCollection(lock, delegate.values) }
-
- override fun clear() = lock.withLock { delegate.clear() }
- override fun isEmpty(): Boolean = lock.withLock { delegate.isEmpty() }
- override fun remove(key: K): V? = lock.withLock { delegate.remove(key) }
- override fun putAll(from: Map) = lock.withLock { delegate.putAll(from) }
- override fun put(key: K, value: V): V? = lock.withLock { delegate.put(key, value) }
- override fun get(key: K): V? = lock.withLock { delegate.get(key) }
- override fun containsValue(value: V): Boolean = lock.withLock { delegate.containsValue(value) }
- override fun containsKey(key: K): Boolean = lock.withLock { delegate.containsKey(key) }
-
- override fun equals(other: Any?): Boolean = delegate == other
- override fun hashCode(): Int = delegate.hashCode()
- override fun toString(): String = delegate.toString()
-}
-
-@Suppress("FunctionName")
-public actual fun ConcurrentLinkedDeque(): MutableDeque {
- return LockedConcurrentArrayDeque(reentrantLock())
-}
-
-private class LockedConcurrentArrayDeque(
- private val lock: ReentrantLock,
- private val delegate: ArrayDeque = ArrayDeque()
-) : MutableDeque {
- override fun addFirst(element: E) = lock.withLock { delegate.addFirst(element) }
-
- override fun add(element: E): Boolean {
- lock.withLock { delegate.add(element) }
- return true
- }
-
- override fun poll(): E? = lock.withLock { delegate.removeFirstOrNull() }
-
- override fun offer(element: E): Boolean {
- lock.withLock { delegate.addLast(element) }
- return true
- }
-
- override val size: Int
- get() = lock.withLock { delegate.size }
-
- override fun clear() = lock.withLock { delegate.clear() }
- override fun addAll(elements: Collection): Boolean = lock.withLock { delegate.addAll(elements) }
- override fun isEmpty(): Boolean = lock.withLock { delegate.isEmpty() }
- override fun iterator(): MutableIterator = delegate.iterator()
- override fun retainAll(elements: Collection): Boolean = lock.withLock { delegate.retainAll(elements) }
- override fun removeAll(elements: Collection): Boolean = lock.withLock { delegate.removeAll(elements) }
- override fun remove(element: E): Boolean = lock.withLock { delegate.remove(element) }
- override fun containsAll(elements: Collection): Boolean = lock.withLock { delegate.containsAll(elements) }
- override fun contains(element: E): Boolean = lock.withLock { delegate.contains(element) }
-
- override fun equals(other: Any?): Boolean = delegate == other
- override fun hashCode(): Int = delegate.hashCode()
- override fun toString(): String = delegate.toString()
-}
-
-internal class ArrayDequeAsMutableDeque(
- private val delegate: ArrayDeque = ArrayDeque()
-) : MutableDeque {
- override fun addFirst(element: E) = delegate.addFirst(element)
-
- override fun add(element: E): Boolean {
- delegate.add(element)
- return true
- }
-
- override fun poll(): E? = delegate.removeFirstOrNull()
-
- override fun offer(element: E): Boolean {
- delegate.addLast(element)
- return true
- }
-
- override val size: Int
- get() = delegate.size
-
- override fun clear() = delegate.clear()
- override fun addAll(elements: Collection): Boolean = delegate.addAll(elements)
- override fun isEmpty(): Boolean = delegate.isEmpty()
- override fun iterator(): MutableIterator = delegate.iterator()
- override fun retainAll(elements: Collection): Boolean = delegate.retainAll(elements)
- override fun removeAll(elements: Collection): Boolean = delegate.removeAll(elements)
- override fun remove(element: E): Boolean = delegate.remove(element)
- override fun containsAll(elements: Collection): Boolean = delegate.containsAll(elements)
- override fun contains(element: E): Boolean = delegate.contains(element)
-
- override fun equals(other: Any?): Boolean = delegate == other
- override fun hashCode(): Int = delegate.hashCode()
- override fun toString(): String = delegate.toString()
-}
-
-@Suppress("FunctionName")
-public actual fun , V> EnumMap(clazz: KClass): MutableMap = mutableMapOf()
-
-@Suppress("FunctionName")
-public actual fun ConcurrentSet(): MutableSet {
- return LockedConcurrentHashSet(reentrantLock())
-}
-
-public actual class LinkedList(
- private val delegate: ArrayDeque
-) : MutableList by delegate {
- public actual constructor() : this(ArrayDeque())
-
- public actual fun addLast(element: E) {
- return delegate.addLast(element)
- }
-}
-
-public actual interface MutableDeque : MutableQueue {
- public actual fun addFirst(element: E)
-}
-
-public actual interface MutableQueue : MutableCollection {
- /**
- * Adds the specified element to the collection.
- *
- * @return `true` if the element has been added, `false` if the collection does not support duplicates
- * and the element is already contained in the collection.
- * @throws IllegalStateException if the queue is full.
- */
- public actual override fun add(element: E): Boolean
-
- /**
- * Removes and returns the head of the queue, `null` otherwise.
- */
- public actual fun poll(): E?
-
- /**
- * Adds an element into the queue.
- * @return `true` if the element has been added, `false` if queue is full.
- */
- public actual fun offer(element: E): Boolean
-
-
-}
-
-/**
- * Returns a [List] that cannot be cast to [MutableList] to modify it.
- */
-public actual fun List.asImmutable(): List = ImmutableList(this)
-public actual fun Collection.asImmutable(): Collection = ImmutableCollection(this)
-public actual fun Set.asImmutable(): Set = ImmutableSet(this)
-
-internal class ImmutableList(
- private val delegate: List
-) : List by delegate
-
-internal class ImmutableCollection(
- private val delegate: Collection
-) : Collection by delegate
-
-internal class ImmutableSet(
- private val delegate: Set
-) : Set by delegate
diff --git a/mirai-core-utils/src/nativeMain/kotlin/CommonDigest.kt b/mirai-core-utils/src/nativeMain/kotlin/CommonDigest.kt
deleted file mode 100644
index 63562ca1a..000000000
--- a/mirai-core-utils/src/nativeMain/kotlin/CommonDigest.kt
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import kotlin.math.abs
-import kotlin.math.min
-import kotlin.math.sin
-
-/*
- * Note: All the declarations in this file are copied from 'com.soywiz.korlibs.krypto'.
- *
- * The license is attached:
-
-MIT License
-
-Copyright (c) 2017 Carlos Ballesteros Velasco
-
-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.
-
-----------------------------------
-
-/**
- * Based on CryptoJS v3.1.2
- * code.google.com/p/crypto-js
- * (c) 2009-2013 by Jeff Mott. All rights reserved.
- * https://github.com/brix/crypto-js/blob/develop/LICENSE
- */
- */
-
-internal inline fun Int.ext8(offset: Int) = (this ushr offset) and 0xFF
-
-internal fun Int.rotateRight(amount: Int): Int = (this ushr amount) or (this shl (32 - amount))
-internal fun Int.rotateLeft(bits: Int): Int = ((this shl bits) or (this ushr (32 - bits)))
-
-internal fun arraycopy(src: ByteArray, srcPos: Int, dst: ByteArray, dstPos: Int, count: Int) =
- src.copyInto(dst, dstPos, srcPos, srcPos + count)
-
-internal fun arraycopy(src: IntArray, srcPos: Int, dst: IntArray, dstPos: Int, count: Int) =
- src.copyInto(dst, dstPos, srcPos, srcPos + count)
-
-internal fun ByteArray.readU8(o: Int): Int = this[o].toInt() and 0xFF
-internal fun ByteArray.readS32_be(o: Int): Int =
- (readU8(o + 3) shl 0) or (readU8(o + 2) shl 8) or (readU8(o + 1) shl 16) or (readU8(o + 0) shl 24)
-
-internal abstract class Hasher(val chunkSize: Int, val digestSize: Int) {
- private val chunk = ByteArray(chunkSize)
- private var writtenInChunk = 0
- private var totalWritten = 0L
-
- fun reset(): Hasher {
- coreReset()
- writtenInChunk = 0
- totalWritten = 0L
- return this
- }
-
- fun update(data: ByteArray, offset: Int, count: Int): Hasher {
- var curr = offset
- var left = count
- while (left > 0) {
- val remainingInChunk = chunkSize - writtenInChunk
- val toRead = min(remainingInChunk, left)
- arraycopy(data, curr, chunk, writtenInChunk, toRead)
- left -= toRead
- curr += toRead
- writtenInChunk += toRead
- if (writtenInChunk >= chunkSize) {
- writtenInChunk -= chunkSize
- coreUpdate(chunk)
- }
- }
- totalWritten += count
- return this
- }
-
- fun digestOut(out: ByteArray) {
- val pad = corePadding(totalWritten)
- var padPos = 0
- while (padPos < pad.size) {
- val padSize = chunkSize - writtenInChunk
- arraycopy(pad, padPos, chunk, writtenInChunk, padSize)
- coreUpdate(chunk)
- writtenInChunk = 0
- padPos += padSize
- }
-
- coreDigest(out)
- coreReset()
- }
-
- protected abstract fun coreReset()
- protected abstract fun corePadding(totalWritten: Long): ByteArray
- protected abstract fun coreUpdate(chunk: ByteArray)
- protected abstract fun coreDigest(out: ByteArray)
-
- fun update(data: ByteArray) = update(data, 0, data.size)
- fun digest(): Hash = Hash(ByteArray(digestSize).also { digestOut(it) })
-}
-
-internal value class Hash(val bytes: ByteArray)
-
-internal open class HasherFactory(val create: () -> Hasher) {
- fun digest(data: ByteArray) = create().also { it.update(data, 0, data.size) }.digest()
-
- inline fun digest(temp: ByteArray = ByteArray(0x1000), readBytes: (data: ByteArray) -> Int): Hash =
- this.create().also {
- while (true) {
- val count = readBytes(temp)
- if (count <= 0) break
- it.update(temp, 0, count)
- }
- }.digest()
-}
-
-internal class MD5 : Hasher(chunkSize = 64, digestSize = 16) {
- companion object : HasherFactory({ MD5() }) {
- private val S = intArrayOf(7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21)
- private val T = IntArray(64) { ((1L shl 32) * abs(sin(1.0 + it))).toLong().toInt() }
- }
-
- private val r = IntArray(4)
- private val o = IntArray(4)
- private val b = IntArray(16)
-
- init {
- coreReset()
- }
-
- override fun coreReset() {
- r[0] = 0x67452301
- r[1] = 0xEFCDAB89.toInt()
- r[2] = 0x98BADCFE.toInt()
- r[3] = 0x10325476
- }
-
- override fun coreUpdate(chunk: ByteArray) {
- for (j in 0 until 64) b[j ushr 2] = (chunk[j].toInt() shl 24) or (b[j ushr 2] ushr 8)
- for (j in 0 until 4) o[j] = r[j]
- for (j in 0 until 64) {
- val d16 = j / 16
- val f = when (d16) {
- 0 -> (r[1] and r[2]) or (r[1].inv() and r[3])
- 1 -> (r[1] and r[3]) or (r[2] and r[3].inv())
- 2 -> r[1] xor r[2] xor r[3]
- 3 -> r[2] xor (r[1] or r[3].inv())
- else -> 0
- }
- val bi = when (d16) {
- 0 -> j
- 1 -> (j * 5 + 1) and 0x0F
- 2 -> (j * 3 + 5) and 0x0F
- 3 -> (j * 7) and 0x0F
- else -> 0
- }
- val temp = r[1] + (r[0] + f + b[bi] + T[j]).rotateLeft(S[(d16 shl 2) or (j and 3)])
- r[0] = r[3]
- r[3] = r[2]
- r[2] = r[1]
- r[1] = temp
- }
- for (j in 0 until 4) r[j] += o[j]
- }
-
- override fun corePadding(totalWritten: Long): ByteArray {
- val numberOfBlocks = ((totalWritten + 8) / chunkSize) + 1
- val totalWrittenBits = totalWritten * 8
- return ByteArray(((numberOfBlocks * chunkSize) - totalWritten).toInt()).apply {
- this[0] = 0x80.toByte()
- for (i in 0 until 8) this[this.size - 8 + i] = (totalWrittenBits ushr (8 * i)).toByte()
- }
- }
-
- override fun coreDigest(out: ByteArray) {
- for (it in 0 until 16) out[it] = (r[it / 4] ushr ((it % 4) * 8)).toByte()
- }
-}
-
-internal abstract class SHA(chunkSize: Int, digestSize: Int) : Hasher(chunkSize, digestSize) {
- override fun corePadding(totalWritten: Long): ByteArray {
- val tail = totalWritten % 64
- val padding = (if (64 - tail >= 9) 64 - tail else 128 - tail)
- val pad = ByteArray(padding.toInt()).apply { this[0] = 0x80.toByte() }
- val bits = (totalWritten * 8)
- for (i in 0 until 8) pad[pad.size - 1 - i] = ((bits ushr (8 * i)) and 0xFF).toByte()
- return pad
- }
-}
-
-internal class SHA1 : SHA(chunkSize = 64, digestSize = 20) {
- companion object : HasherFactory({ SHA1() }) {
- private val H = intArrayOf(
- 0x67452301L.toInt(),
- 0xEFCDAB89L.toInt(),
- 0x98BADCFEL.toInt(),
- 0x10325476L.toInt(),
- 0xC3D2E1F0L.toInt()
- )
-
- private const val K0020: Int = 0x5A827999L.toInt()
- private const val K2040: Int = 0x6ED9EBA1L.toInt()
- private const val K4060: Int = 0x8F1BBCDCL.toInt()
- private const val K6080: Int = 0xCA62C1D6L.toInt()
- }
-
- private val w = IntArray(80)
- private val h = IntArray(5)
-
- override fun coreReset(): Unit {
- arraycopy(H, 0, h, 0, 5)
- }
-
- init {
- coreReset()
- }
-
- override fun coreUpdate(chunk: ByteArray) {
- for (j in 0 until 16) w[j] = chunk.readS32_be(j * 4)
- for (j in 16 until 80) w[j] = (w[j - 3] xor w[j - 8] xor w[j - 14] xor w[j - 16]).rotateLeft(1)
-
- var a = h[0]
- var b = h[1]
- var c = h[2]
- var d = h[3]
- var e = h[4]
-
- for (j in 0 until 80) {
- val temp = a.rotateLeft(5) + e + w[j] + when (j / 20) {
- 0 -> ((b and c) or ((b.inv()) and d)) + K0020
- 1 -> (b xor c xor d) + K2040
- 2 -> ((b and c) xor (b and d) xor (c and d)) + K4060
- else -> (b xor c xor d) + K6080
- }
-
- e = d
- d = c
- c = b.rotateLeft(30)
- b = a
- a = temp
- }
-
- h[0] += a
- h[1] += b
- h[2] += c
- h[3] += d
- h[4] += e
- }
-
- override fun coreDigest(out: ByteArray) {
- for (n in out.indices) out[n] = (h[n / 4] ushr (24 - 8 * (n % 4))).toByte()
- }
-}
-
-internal class SHA256 : SHA(chunkSize = 64, digestSize = 32) {
- companion object : HasherFactory({ SHA256() }) {
- private val H = intArrayOf(
- 0x6a09e667, -0x4498517b, 0x3c6ef372, -0x5ab00ac6,
- 0x510e527f, -0x64fa9774, 0x1f83d9ab, 0x5be0cd19
- )
-
- private val K = intArrayOf(
- 0x428a2f98, 0x71374491, -0x4a3f0431, -0x164a245b,
- 0x3956c25b, 0x59f111f1, -0x6dc07d5c, -0x54e3a12b,
- -0x27f85568, 0x12835b01, 0x243185be, 0x550c7dc3,
- 0x72be5d74, -0x7f214e02, -0x6423f959, -0x3e640e8c,
- -0x1b64963f, -0x1041b87a, 0x0fc19dc6, 0x240ca1cc,
- 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
- -0x67c1aeae, -0x57ce3993, -0x4ffcd838, -0x40a68039,
- -0x391ff40d, -0x2a586eb9, 0x06ca6351, 0x14292967,
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
- 0x650a7354, 0x766a0abb, -0x7e3d36d2, -0x6d8dd37b,
- -0x5d40175f, -0x57e599b5, -0x3db47490, -0x3893ae5d,
- -0x2e6d17e7, -0x2966f9dc, -0xbf1ca7b, 0x106aa070,
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
- 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
- 0x748f82ee, 0x78a5636f, -0x7b3787ec, -0x7338fdf8,
- -0x6f410006, -0x5baf9315, -0x41065c09, -0x398e870e
- )
- }
-
-
- private val h = IntArray(8)
- private val r = IntArray(8)
- private val w = IntArray(64)
-
- init {
- coreReset()
- }
-
- override fun coreReset() {
- arraycopy(H, 0, h, 0, 8)
- }
-
- override fun coreUpdate(chunk: ByteArray) {
- arraycopy(h, 0, r, 0, 8)
-
- for (j in 0 until 16) w[j] = chunk.readS32_be(j * 4)
- for (j in 16 until 64) {
- val s0 = w[j - 15].rotateRight(7) xor w[j - 15].rotateRight(18) xor w[j - 15].ushr(3)
- val s1 = w[j - 2].rotateRight(17) xor w[j - 2].rotateRight(19) xor w[j - 2].ushr(10)
- w[j] = w[j - 16] + s0 + w[j - 7] + s1
- }
-
- for (j in 0 until 64) {
- val s1 = r[4].rotateRight(6) xor r[4].rotateRight(11) xor r[4].rotateRight(25)
- val ch = r[4] and r[5] xor (r[4].inv() and r[6])
- val t1 = r[7] + s1 + ch + K[j] + w[j]
- val s0 = r[0].rotateRight(2) xor r[0].rotateRight(13) xor r[0].rotateRight(22)
- val maj = r[0] and r[1] xor (r[0] and r[2]) xor (r[1] and r[2])
- val t2 = s0 + maj
- r[7] = r[6]
- r[6] = r[5]
- r[5] = r[4]
- r[4] = r[3] + t1
- r[3] = r[2]
- r[2] = r[1]
- r[1] = r[0]
- r[0] = t1 + t2
-
- }
- for (j in 0 until 8) h[j] += r[j]
- }
-
- override fun coreDigest(out: ByteArray) {
- for (n in out.indices) out[n] = (h[n / 4] ushr (24 - 8 * (n % 4))).toByte()
- }
-}
-
diff --git a/mirai-core-utils/src/nativeMain/kotlin/CoroutineUtils.kt b/mirai-core-utils/src/nativeMain/kotlin/CoroutineUtils.kt
deleted file mode 100644
index 6beaf0c77..000000000
--- a/mirai-core-utils/src/nativeMain/kotlin/CoroutineUtils.kt
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-@file:Suppress("RedundantVisibilityModifier")
-
-package net.mamoe.mirai.utils
-
-public actual suspend inline fun runBIO(noinline block: () -> R): R {
- return block()
-}
-
-public actual suspend inline fun T.runBIO(crossinline block: T.() -> R): R {
- return block()
-}
-
-/**
- * For code
- * ```
- * try {
- * job(new)
- * } catch (e: Throwable) {
- * throw IllegalStateException("Exception in attached Job '$name'", e.unwrapCancellationException())
- * }
- * ```
- *
- * Original stacktrace, you mainly see `StateSwitchingException` which is useless to locate the code where real cause `ForceOfflineException` is thrown.
- * ```
- * Exception in thread "DefaultDispatcher-worker-1 @BotInitProcessor.init#7" java.lang.IllegalStateException: Exception in attached Job 'BotInitProcessor.init'
- * at net.mamoe.mirai.internal.network.handler.state.JobAttachStateObserver$stateChanged0$1.invokeSuspend(JobAttachStateObserver.kt:40)
- * at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
- * at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
- * at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
- * at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
- * at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
- * at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
- * Caused by: StateSwitchingException(old=StateLoading, new=StateClosed, cause=net.mamoe.mirai.internal.network.impl.netty.ForceOfflineException: Closed by MessageSvc.PushForceOffline: net.mamoe.mirai.internal.network.protocol.data.jce.RequestPushForceOffline@4abf6d30)
- * at net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport.setStateImpl$mirai_core(NetworkHandlerSupport.kt:258)
- * at net.mamoe.mirai.internal.network.impl.netty.NettyNetworkHandler.close(NettyNetworkHandler.kt:404)
- * ```
- *
- * Real stacktrace (with [unwrapCancellationException]), you directly have `ForceOfflineException`, also you wont lose information of `StateSwitchingException`
- * ```
- * Exception in thread "DefaultDispatcher-worker-2 @BotInitProcessor.init#7" java.lang.IllegalStateException: Exception in attached Job 'BotInitProcessor.init'
- * at net.mamoe.mirai.internal.network.handler.state.JobAttachStateObserver$stateChanged0$1.invokeSuspend(JobAttachStateObserver.kt:40)
- * at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
- * at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
- * at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
- * at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
- * at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
- * at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
- * Caused by: net.mamoe.mirai.internal.network.impl.netty.ForceOfflineException: Closed by MessageSvc.PushForceOffline: net.mamoe.mirai.internal.network.protocol.data.jce.RequestPushForceOffline@62f65f94
- * at net.mamoe.mirai.utils.MiraiUtils__CoroutineUtilsKt.unwrapCancellationException(CoroutineUtils.kt:141)
- * at net.mamoe.mirai.utils.MiraiUtils.unwrapCancellationException(Unknown Source)
- * ... 7 more
- * Suppressed: StateSwitchingException(old=StateLoading, new=StateClosed, cause=net.mamoe.mirai.internal.network.impl.netty.ForceOfflineException: Closed by MessageSvc.PushForceOffline: net.mamoe.mirai.internal.network.protocol.data.jce.RequestPushForceOffline@62f65f94)
- * at net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport.setStateImpl$mirai_core(NetworkHandlerSupport.kt:258)
- * at net.mamoe.mirai.internal.network.impl.netty.NettyNetworkHandler.close(NettyNetworkHandler.kt:404)
- * ```
- */
-@Suppress("unused")
-public actual inline fun Throwable.unwrap(addSuppressed: Boolean): Throwable {
- if (this !is E) return this
- return this.findCause { it !is E }
- ?.also { if (addSuppressed) it.addSuppressed(this) }
- ?: this
-}
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeMain/kotlin/ExceptionCollector.kt b/mirai-core-utils/src/nativeMain/kotlin/ExceptionCollector.kt
deleted file mode 100644
index 38386cdaa..000000000
--- a/mirai-core-utils/src/nativeMain/kotlin/ExceptionCollector.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-internal actual fun hash(e: Throwable): Long {
- var hashCode = 1L
- val trace = e.getStackTraceAddresses()
- for (stackTraceAddress in trace) {
- hashCode = (hashCode xor stackTraceAddress).shl(1)
- }
-
- // Somehow stacktrace analysis is on my own Windows machine but not on GitHub Actions.
- // Hashing with a class to tentatively not filter out different types.
- return hashCode xor e::class.hashCode().toLongUnsigned()
-}
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeMain/kotlin/MiraiFile.kt b/mirai-core-utils/src/nativeMain/kotlin/MiraiFile.kt
deleted file mode 100644
index 798037742..000000000
--- a/mirai-core-utils/src/nativeMain/kotlin/MiraiFile.kt
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-@file:Suppress("RedundantVisibilityModifier")
-
-package net.mamoe.mirai.utils
-
-import io.ktor.utils.io.bits.*
-import io.ktor.utils.io.core.*
-import io.ktor.utils.io.errors.*
-import kotlinx.cinterop.*
-import platform.posix.*
-
-/**
- * Multiplatform implementation of file operations.
- */
-public actual interface MiraiFile {
- /**
- * Name of this file or directory. Can be '.' and '..' if created by
- */
- public actual val name: String
-
- /**
- * Parent of this file or directory.
- */
- public actual val parent: MiraiFile?
-
- /**
- * Input path from [create].
- */
- public actual val path: String
-
- /**
- * Normalized absolute [path].
- */
- public actual val absolutePath: String
- public actual val length: Long
- public actual val isFile: Boolean
- public actual val isDirectory: Boolean
- public actual fun exists(): Boolean
-
- /**
- * Resolves a [MiraiFile] representing the [path] based on this [MiraiFile]. Result path is not guaranteed to be normalized.
- */
- public actual fun resolve(path: String): MiraiFile
- public actual fun resolve(file: MiraiFile): MiraiFile
- public actual fun createNewFile(): Boolean
- public actual fun delete(): Boolean
- public actual fun mkdir(): Boolean
- public actual fun mkdirs(): Boolean
- public actual fun input(): Input
- public actual fun output(): Output
-
- public actual companion object {
- public actual fun create(path: String): MiraiFile = MiraiFileImpl(path)
- public actual fun getWorkingDir(): MiraiFile = MiraiFileImpl.getWorkingDir()
- }
-}
-
-
-private val deleteFile =
- staticCFunction>?, CPointer?, Int, CPointer?, Int> { pathPtr, _, _, _ ->
- val path = pathPtr!!.toKString()
- if (remove(path) < 0) {
- -1
- } else {
- 0
- }
- }
-
-public actual fun MiraiFile.deleteRecursively(): Boolean {
- return nftw(absolutePath, deleteFile, 10, FTW_DEPTH or FTW_MOUNT or FTW_PHYS) >= 0
-}
-
-internal expect class MiraiFileImpl(path: String) : MiraiFile {
- companion object {
- public fun getWorkingDir(): MiraiFile
- }
-}
-
-
-/*
- Data from https://man7.org/linux/man-pages/man2/lstat.2.html
-
-
- st_dev This field describes the device on which this file
- resides. (The major(3) and minor(3) macros may be useful
- to decompose the device ID in this field.)
-
- st_ino This field contains the file's inode number.
-
- st_mode
- This field contains the file type and mode. See inode(7)
- for further information.
-
- S_IFMT 0170000 bit mask for the file type bit field
-
- S_IFSOCK 0140000 socket
- S_IFLNK 0120000 symbolic link
- S_IFREG 0100000 regular file
- S_IFBLK 0060000 block device
- S_IFDIR 0040000 directory
- S_IFCHR 0020000 character device
- S_IFIFO 0010000 FIFO
-
-
- st_nlink
- This field contains the number of hard links to the file.
-
- st_uid This field contains the user ID of the owner of the file.
-
- st_gid This field contains the ID of the group owner of the file.
-
- st_rdev
- This field describes the device that this file (inode)
- represents.
-
- st_size
- This field gives the size of the file (if it is a regular
- file or a symbolic link) in bytes. The size of a symbolic
- link is the length of the pathname it contains, without a
- terminating null byte.
-
- st_blksize
- This field gives the "preferred" block size for efficient
- filesystem I/O.
-
- st_blocks
- This field indicates the number of blocks allocated to the
- file, in 512-byte units. (This may be smaller than
- st_size/512 when the file has holes.)
-
- st_atime
- This is the time of the last access of file data.
-
- st_mtime
- This is the time of last modification of file data.
-
- st_ctime
- This is the file's last status change timestamp (time of
- last change to the inode).
-
- */
-internal inline fun MiraiFileImpl.useStat(block: (stat) -> R): R? {
- memScoped {
- val stat = alloc()
- val ret = stat(absolutePath, stat.ptr)
- if (ret != 0) return null
- return block(stat)
- }
-}
-
-internal class FileNotFoundException(message: String, cause: Throwable? = null) :
- IOException(message, cause)
-
-
-@Suppress("DEPRECATION")
-internal class PosixFileInstanceOutput(val file: CPointer) : Output() {
- private var closed = false
-
- override fun flush(source: Memory, offset: Int, length: Int) {
- val end = offset + length
- var currentOffset = offset
-
- while (currentOffset < end) {
- val result = fwrite(
- source.pointer + currentOffset.convert(),
- sizeOf().convert(),
- (end - currentOffset).convert(),
- file.cast()
- ).convert()
- if (result == 0) {
- throw PosixException.forErrno(posixFunctionName = "fwrite()").wrapIO()
- }
- currentOffset += result
- }
- }
-
- override fun closeDestination() {
- if (closed) return
- closed = true
-
- if (fclose(file) != 0) {
- throw PosixException.forErrno(posixFunctionName = "fclose").wrapIO()
- }
- }
-}
-
-@Suppress("DEPRECATION")
-internal class PosixInputForFile(val file: CPointer) : Input() {
- private var closed = false
-
- override fun fill(destination: Memory, offset: Int, length: Int): Int {
- val size = fread(
- destination.pointer + offset.convert(),
- sizeOf().convert(),
- length.convert(),
- file.cast()
- ).toInt()
- if (size == 0) {
- if (feof(file) != 0) return 0
- throw PosixException.forErrno(posixFunctionName = "read()").wrapIO()
- }
-
- return size
- }
-
- override fun closeSource() {
- if (closed) return
- closed = true
-
- if (fclose(file) != 0) {
- throw PosixException.forErrno(posixFunctionName = "fclose()").wrapIO()
- }
- }
-}
-
-public fun PosixException.wrapIO(): IOException =
- IOException("I/O operation failed due to posix error code $errno", this)
diff --git a/mirai-core-utils/src/nativeMain/kotlin/NativePlatformSupport.kt b/mirai-core-utils/src/nativeMain/kotlin/NativePlatformSupport.kt
deleted file mode 100644
index 9c930c234..000000000
--- a/mirai-core-utils/src/nativeMain/kotlin/NativePlatformSupport.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import kotlinx.cinterop.*
-
-public inline infix fun UShort.flag(flag: UShort): Boolean = this and flag != 0u.toUShort()
-public inline infix fun UInt.flag(flag: UInt): Boolean = this and flag != 0u
-public inline infix fun UInt.flag(flag: Int): Boolean = this and flag.toUInt() != 0u
-public inline infix fun Int.flag(flag: UInt): Boolean = this.toUInt() and flag != 0u
-public inline infix fun ULong.flag(flag: ULong): Boolean = this and flag != 0uL
-
-public val NULL_PTR: COpaquePointerVar = nativeHeap.alloc()
-public inline fun nullPtr(): T = NULL_PTR.reinterpret()
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeMain/kotlin/SecretsProtection.kt b/mirai-core-utils/src/nativeMain/kotlin/SecretsProtection.kt
deleted file mode 100644
index a83b31818..000000000
--- a/mirai-core-utils/src/nativeMain/kotlin/SecretsProtection.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import kotlinx.serialization.KSerializer
-import kotlinx.serialization.builtins.ByteArraySerializer
-import kotlinx.serialization.builtins.serializer
-
-internal actual object SecretsProtectionPlatform {
- actual fun impl_asString(data: Any): String {
- return (data as ByteArray).decodeToString()
- }
-
- actual fun impl_asByteArray(data: Any): ByteArray {
- return data as ByteArray
- }
-
- actual fun impl_getSize(data: Any): Int {
- return data.cast().size
- }
-
- actual fun escape(data: ByteArray): Any {
- return data
- }
-
- actual object EscapedStringSerializer : KSerializer by String.serializer().map(
- String.serializer().descriptor.copy("EscapedString"),
- deserialize = { SecretsProtection.EscapedString(it.encodeToByteArray()) },
- serialize = { it.data.cast().decodeToString() }
- )
-
- actual object EscapedByteBufferSerializer :
- KSerializer by ByteArraySerializer().map(
- ByteArraySerializer().descriptor.copy("EscapedByteBuffer"),
- deserialize = { SecretsProtection.EscapedByteBuffer(it) },
- serialize = { it.data.cast() }
- )
-
-
-}
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeMain/kotlin/Service.kt b/mirai-core-utils/src/nativeMain/kotlin/Service.kt
deleted file mode 100644
index c74f7e495..000000000
--- a/mirai-core-utils/src/nativeMain/kotlin/Service.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-@file:Suppress("RedundantVisibilityModifier")
-
-package net.mamoe.mirai.utils
-
-import net.mamoe.mirai.utils.Services.qualifiedNameOrFail
-import kotlin.reflect.KClass
-
-@Suppress("UNCHECKED_CAST")
-public actual fun loadServiceOrNull(
- clazz: KClass,
- fallbackImplementation: String?
-): T? =
- Services.firstImplementationOrNull(qualifiedNameOrFail(clazz)) as T?
-
-public actual fun loadService(
- clazz: KClass,
- fallbackImplementation: String?
-): T = loadServiceOrNull(clazz, fallbackImplementation)
- ?: error("Could not load service '${clazz.qualifiedName ?: clazz}'. Current services: ${Services.print()}")
-
-public actual fun loadServices(clazz: KClass): Sequence =
- Services.implementations(qualifiedNameOrFail(clazz)).orEmpty().map { it.value }.castUp()
diff --git a/mirai-core-utils/src/nativeMain/kotlin/StandardUtils.kt b/mirai-core-utils/src/nativeMain/kotlin/StandardUtils.kt
deleted file mode 100644
index a8ab13b3d..000000000
--- a/mirai-core-utils/src/nativeMain/kotlin/StandardUtils.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-
-public actual fun localIpAddress(): String = "192.168.1.123"
-
-internal actual fun isSameClassPlatform(object1: Any, object2: Any): Boolean {
- return object1::class == object2::class
-}
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeMain/kotlin/StructureToStringTransformer.kt b/mirai-core-utils/src/nativeMain/kotlin/StructureToStringTransformer.kt
deleted file mode 100644
index b1bb3d47f..000000000
--- a/mirai-core-utils/src/nativeMain/kotlin/StructureToStringTransformer.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-internal actual fun getPlatformDefaultStructureToStringTransformer(): StructureToStringTransformer? {
- return null
-}
diff --git a/mirai-core-utils/src/nativeMain/kotlin/TimeUtils.kt b/mirai-core-utils/src/nativeMain/kotlin/TimeUtils.kt
deleted file mode 100644
index 83fd24a4a..000000000
--- a/mirai-core-utils/src/nativeMain/kotlin/TimeUtils.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-@file:Suppress("RedundantVisibilityModifier")
-
-package net.mamoe.mirai.utils
-
-import kotlinx.atomicfu.locks.ReentrantLock
-import kotlinx.atomicfu.locks.withLock
-import kotlinx.cinterop.*
-import platform.posix.*
-
-/**
- * 时间戳
- */
-@OptIn(UnsafeNumber::class)
-public actual fun currentTimeMillis(): Long {
- // Do not use getTimeMillis from stdlib, it doesn't support iosSimulatorArm64
- memScoped {
- val spec = alloc()
- clock_gettime(CLOCK_REALTIME.convert(), spec.ptr)
- return (spec.tv_sec * 1000 + spec.tv_nsec.convert() / 1e6).toLong()
- }
-}
-
-
-private val timeLock = ReentrantLock()
-
-public actual fun formatTime(epochTimeMillis: Long, format: String?): String = timeLock.withLock {
- val strftimeFormat = format
- ?.replace("yyyy", "%Y")
- ?.replace("MM", "%m")
- ?.replace("dd", "%d")
- ?.replace("HH", "%H")
- ?.replace("mm", "%M")
- ?.replace("ss", "%S")
- ?: "%Y-%m-%d %H:%M:%S"
- memScoped {
- val timeT = alloc()
- timeT.value = epochTimeMillis / 1000
-
- // http://www.cplusplus.com/reference/clibrary/ctime/localtime/
- // tm returns a static pointer which doesn't need to free
- val tm = localtime(timeT.ptr) // localtime is not thread-safe
-
- val bb = allocArray(40)
-
- strftime(bb, 40, strftimeFormat, tm);
-
- bb.toKString()
- }
-}
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeMain/kotlin/cipher.rs b/mirai-core-utils/src/nativeMain/kotlin/cipher.rs
deleted file mode 100644
index e69de29bb..000000000
diff --git a/mirai-core-utils/src/nativeMain/kotlin/getProperty.kt b/mirai-core-utils/src/nativeMain/kotlin/getProperty.kt
deleted file mode 100644
index 1ee367d81..000000000
--- a/mirai-core-utils/src/nativeMain/kotlin/getProperty.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-private val properties: MutableMap = ConcurrentHashMap()
-
-internal actual fun getProperty(name: String, default: String): String? {
- return properties.getOrElse(name) { default }
-}
-
-internal actual fun setProperty(name: String, value: String) {
- properties[name] = value
-}
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeMainInterop/.gitignore b/mirai-core-utils/src/nativeMainInterop/.gitignore
deleted file mode 100644
index 683119ebf..000000000
--- a/mirai-core-utils/src/nativeMainInterop/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-/target
-Cargo.lock
-myrust.h
-
-*.iml
-
-src/bindings.rs
-/*.h
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeMainInterop/Cargo.toml b/mirai-core-utils/src/nativeMainInterop/Cargo.toml
deleted file mode 100644
index 4e35d2e0a..000000000
--- a/mirai-core-utils/src/nativeMainInterop/Cargo.toml
+++ /dev/null
@@ -1,19 +0,0 @@
-[package]
-name = "mirai_core_utils_i"
-version = "0.1.0"
-
-[dependencies]
-md5 = "0.7.0"
-sha1 = "0.10.1"
-flate2 = "1.0.23"
-libc = "0.2.126"
-#chashmap = "2.2.2"
-
-[lib]
-name = "mirai_core_utils_i"
-crate-type = ["cdylib"] # Creates dynamic lib
-# crate-type = ["staticlib"] # Creates static lib
-
-[build-dependencies]
-bindgen = "0.53.1"
-cbindgen = "0.20.0"
diff --git a/mirai-core-utils/src/nativeMainInterop/build.rs b/mirai-core-utils/src/nativeMainInterop/build.rs
deleted file mode 100644
index 669efe88f..000000000
--- a/mirai-core-utils/src/nativeMainInterop/build.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-extern crate bindgen;
-extern crate cbindgen;
-
-use std::env;
-use std::path::PathBuf;
-
-use cbindgen::Config;
-use cbindgen::Language::C;
-
-fn main() {
- // let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
-
- // cbindgen::Builder::new()
- // .with_crate(crate_dir)
- // .with_language(C)
- // .generate()
- // .expect("Unable to generate bindings")
- // .write_to_file("nativeInterop.h");
-
-
- println!("cargo:rustc-link-search=../../build/bin/native/debugShared");
- println!("cargo:rustc-link-lib=mirai_core_utils");
-}
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeMainInterop/cbindgen.toml b/mirai-core-utils/src/nativeMainInterop/cbindgen.toml
deleted file mode 100644
index 4aa4b4903..000000000
--- a/mirai-core-utils/src/nativeMainInterop/cbindgen.toml
+++ /dev/null
@@ -1,10 +0,0 @@
-# This is a template cbindgen.toml file with all of the default values.
-# Some values are commented out because their absence is the real default.
-#
-# See https://github.com/eqrion/cbindgen/blob/master/docs.md#cbindgentoml
-# for detailed documentation of every option here.
-
-
-
-language = "C"
-
diff --git a/mirai-core-utils/src/nativeMainInterop/interop.def b/mirai-core-utils/src/nativeMainInterop/interop.def
deleted file mode 100644
index e69de29bb..000000000
diff --git a/mirai-core-utils/src/nativeMainInterop/src/chmap.rs b/mirai-core-utils/src/nativeMainInterop/src/chmap.rs
deleted file mode 100644
index 8293ac703..000000000
--- a/mirai-core-utils/src/nativeMainInterop/src/chmap.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-// use std::ops::DerefMut;
-// use std::ptr::{null, null_mut};
-//
-// use chashmap::CHashMap;
-// use libc::c_void;
-// //
-// #[no_mangle]
-// pub extern "C" fn mirai_chmap_create() -> *mut c_void {
-// let map = CHashMap::<*mut c_void, *mut c_void>::new();
-// // Box::into_raw(Box::new(map))
-// return Box::into_raw(Box::new(map)) as *mut c_void;
-// }
-//
-// #[no_mangle]
-// pub unsafe extern "C" fn mirai_chmap_put(map: *const c_void, key: *const c_void, value: *const c_void) -> *const c_void {
-// let chmap = Box::from_raw(map as *mut CHashMap::<*const c_void, *const c_void>);
-// return chmap.insert(key, value).unwrap_or(null());
-// }
diff --git a/mirai-core-utils/src/nativeMainInterop/src/crypto.rs b/mirai-core-utils/src/nativeMainInterop/src/crypto.rs
deleted file mode 100644
index 6efd52b6e..000000000
--- a/mirai-core-utils/src/nativeMainInterop/src/crypto.rs
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-use std::io::{BufReader, Read, Write};
-
-use flate2::Compression;
-use flate2::write::{DeflateDecoder, DeflateEncoder, GzDecoder, GzEncoder, ZlibDecoder, ZlibEncoder};
-use libc::{malloc, read, size_t};
-use sha1::{Digest, Sha1};
-use sha1::digest::{Output, OutputSizeUser};
-use sha1::digest::generic_array::GenericArray;
-
-#[no_mangle]
-#[repr(C)]
-pub struct SizedByteArray {
- arr: *mut u8,
- size: u32,
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn mirai_crypto_md5(data: *const u8, len: u32, ret: &mut SizedByteArray) -> bool {
- let data = unsafe { std::slice::from_raw_parts(data, len as usize) };
- let result = md5::compute(data);
- let size = 16;
- let mut memory = malloc(size).cast();
- memory.copy_from(result.as_ptr(), size);
-
- ret.arr = memory;
- ret.size = size as u32;
- return true;
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn mirai_crypto_sha1(data: *const u8, len: u32, ret: &mut SizedByteArray) -> bool {
- let data = unsafe { std::slice::from_raw_parts(data, len as usize) };
- let mut hasher = Sha1::new();
- hasher.update(data);
- let result = hasher.finalize();
- let size = 16;
- let mut memory = malloc(size).cast();
- memory.copy_from(result.as_ptr(), size);
-
- ret.arr = memory;
- ret.size = size as u32;
- return true;
-}
-
-
-#[no_mangle]
-pub unsafe extern "C" fn mirai_crypto_gzip(data: *const u8, len: u32, ret: &mut SizedByteArray) -> bool {
- let data = unsafe { std::slice::from_raw_parts(data, len as usize) };
- let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
-
- let result = encoder.write_all(data).and_then(|_| { encoder.finish() });
- if result.is_err() { return false; }
- let result = result.unwrap();
-
- let size = result.len();
- let mut memory = malloc(size).cast();
- memory.copy_from(result.as_ptr(), size);
-
- ret.arr = memory;
- ret.size = size as u32;
- return true;
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn mirai_crypto_ungzip(data: *const u8, len: u32, ret: &mut SizedByteArray) -> bool {
- let data = unsafe { std::slice::from_raw_parts(data, len as usize) };
- let mut encoder = GzDecoder::new(Vec::new());
-
- let result = encoder.write_all(data).and_then(|_| { encoder.finish() });
- if result.is_err() { return false; }
- let result = result.unwrap();
-
- let size = result.len();
- let mut memory = malloc(size).cast();
- memory.copy_from(result.as_ptr(), size);
-
- ret.arr = memory;
- ret.size = size as u32;
- return true;
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn mirai_crypto_deflate(data: *const u8, len: u32, ret: &mut SizedByteArray) -> bool {
- let data = unsafe { std::slice::from_raw_parts(data, len as usize) };
- let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
-
- let result = encoder.write_all(data).and_then(|_| { encoder.finish() });
- if result.is_err() { return false; }
- let result = result.unwrap();
-
- let size = result.len();
- let mut memory = malloc(size).cast();
- memory.copy_from(result.as_ptr(), size);
-
- ret.arr = memory;
- ret.size = size as u32;
- return true;
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn mirai_crypto_inflate(data: *const u8, len: u32, ret: &mut SizedByteArray) -> bool {
- let data = unsafe { std::slice::from_raw_parts(data, len as usize) };
- let mut encoder = ZlibDecoder::new(Vec::new());
-
- let result = encoder.write_all(data).and_then(|_| { encoder.finish() });
- if result.is_err() { return false; }
- let result = result.unwrap();
-
- let size = result.len();
- let mut memory = malloc(size).cast();
- memory.copy_from(result.as_ptr(), size);
-
- ret.arr = memory;
- ret.size = size as u32;
- return true;
-}
diff --git a/mirai-core-utils/src/nativeMainInterop/src/lib.rs b/mirai-core-utils/src/nativeMainInterop/src/lib.rs
deleted file mode 100644
index 592b7953c..000000000
--- a/mirai-core-utils/src/nativeMainInterop/src/lib.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-// extern crate chashmap;
-extern crate core;
-extern crate flate2;
-extern crate libc;
-extern crate sha1;
-
-/// cbindgen:ignore
-mod bindings;
-mod crypto;
-mod chmap;
-
diff --git a/mirai-core-utils/src/nativeTest/kotlin/AbstractNativeMiraiFileImplTest.kt b/mirai-core-utils/src/nativeTest/kotlin/AbstractNativeMiraiFileImplTest.kt
deleted file mode 100644
index 2c94a6236..000000000
--- a/mirai-core-utils/src/nativeTest/kotlin/AbstractNativeMiraiFileImplTest.kt
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import io.ktor.utils.io.errors.*
-import kotlin.test.*
-
-internal abstract class AbstractNativeMiraiFileImplTest {
- protected abstract val baseTempDir: MiraiFile // MiraiFile.create("/Users/Shared/mirai_test")
- protected abstract val tempPath: String
- protected val tempDir by lazy {
- MiraiFile.create(tempPath).apply {
- assertTrue("Failed to make temp directory: ${this.absolutePath}") { mkdirs() }
- }
- }
-
- @AfterTest
- fun afterTest() {
- println("Cleaning up...")
- println("deleteRecursively:" + baseTempDir.deleteRecursively())
- }
-
- @BeforeTest
- fun init() {
- println("Test start")
- assertTrue { tempDir.exists() }
- }
-
- @Test
- fun `canonical paths for canonical input`() {
- assertPathEquals(tempPath, tempDir.path)
- assertPathEquals(tempPath, tempDir.absolutePath)
- }
-
- @Test
- protected open fun parent() {
- assertEquals(tempDir, tempDir.resolve("s").parent)
- assertEquals(tempDir.parent, tempDir.resolve(".."))
- }
-
- @Test
- open fun `canonical paths for non-canonical input`() {
- // extra /
- MiraiFile.create("$tempPath/").resolve("test").let {
- assertPathEquals("${tempPath}/test", it.path)
- assertPathEquals("${tempPath}/test", it.absolutePath)
- }
- // extra //
- MiraiFile.create("$tempPath//").resolve("test").let {
- assertPathEquals("${tempPath}/test", it.path)
- assertPathEquals("${tempPath}/test", it.absolutePath)
- }
- // extra /.
- MiraiFile.create("$tempPath/.").resolve("test").let {
- assertPathEquals("${tempPath}/test", it.path)
- assertPathEquals("${tempPath}/test", it.absolutePath)
- }
- // extra /./.
- MiraiFile.create("$tempPath/./.").resolve("test").let {
- assertPathEquals("${tempPath}/test", it.path)
- assertPathEquals("${tempPath}/test", it.absolutePath)
- }
- }
-
- @Test
- abstract fun `resolve absolute`()
-
- @Test
- fun `exits createNewFile mkdir length`() {
- assertTrue { tempDir.exists() }
-
- assertFalse { tempDir.resolve("not_existing_file.txt").exists() }
- assertEquals(0L, tempDir.resolve("not_existing_file.txt").length)
- assertTrue { tempDir.resolve("not_existing_file.txt").createNewFile() }
- assertEquals(0L, tempDir.resolve("not_existing_file.txt").length)
- assertTrue { tempDir.resolve("not_existing_file.txt").exists() }
-
- assertFalse { tempDir.resolve("not_existing_dir").exists() }
- assertEquals(0L, tempDir.resolve("not_existing_dir").length)
- assertTrue { tempDir.resolve("not_existing_dir").mkdir() }
-// assertNotEquals(0L, tempDir.resolve("not_existing_dir").length) // length is platform-dependent, on Windows it is 0 but on unix it is not
- assertTrue { tempDir.resolve("not_existing_dir").exists() }
- }
-
- @Test
- fun `isFile isDirectory`() {
- assertTrue { tempDir.exists() }
-
- println("1")
- assertFalse { tempDir.resolve("not_existing_file.txt").exists() }
- assertEquals(false, tempDir.resolve("not_existing_file.txt").isFile)
- println("1")
- assertEquals(false, tempDir.resolve("not_existing_file.txt").isDirectory)
- println("1")
- assertTrue { tempDir.resolve("not_existing_file.txt").createNewFile() }
- assertEquals(true, tempDir.resolve("not_existing_file.txt").isFile)
- assertEquals(false, tempDir.resolve("not_existing_file.txt").isDirectory)
- println("1")
- assertTrue { tempDir.resolve("not_existing_file.txt").exists() }
-
- println("1")
- assertFalse { tempDir.resolve("not_existing_dir").exists() }
- assertEquals(false, tempDir.resolve("not_existing_dir").isFile)
- assertEquals(false, tempDir.resolve("not_existing_dir").isDirectory)
- println("1")
- assertTrue { tempDir.resolve("not_existing_dir").mkdir() }
- assertEquals(false, tempDir.resolve("not_existing_dir").isFile)
- assertEquals(true, tempDir.resolve("not_existing_dir").isDirectory)
- println("1")
- assertTrue { tempDir.resolve("not_existing_dir").exists() }
- }
-
- @Test
- fun writeText() {
- // new file
- tempDir.resolve("writeText1.txt").let { file ->
- val text = "some text"
- file.writeText(text)
- assertEquals(text.length, file.length.toInt())
- }
-
- // override
- tempDir.resolve("writeText1.txt").let { file ->
- val text = "some other text"
- file.writeText(text)
- assertEquals(text.length, file.length.toInt())
- }
- }
-
- @Test
- fun readText() {
- tempDir.resolve("readText2.txt").let { file ->
- assertTrue { !file.exists() }
- assertFailsWith { file.readText() }
-
- val text = "some text"
- file.writeText(text)
- assertEquals(text, file.readText())
- }
- }
-
- private val bigText = "some text".repeat(10000)
-
- @Test
- fun writeBigText() {
- // new file
- tempDir.resolve("writeText3.txt").let { file ->
- file.writeText(bigText)
- assertEquals(bigText.length, file.length.toInt())
- }
-
- // override
- tempDir.resolve("writeText4.txt").let { file ->
- file.writeText(bigText)
- assertEquals(bigText.length, file.length.toInt())
- }
- }
-
- @Test
- fun readBigText() {
- tempDir.resolve("readText4.txt").let { file ->
- assertTrue { !file.exists() }
- assertFailsWith { file.readText() }
-
- file.writeText(bigText)
- println("reading text")
- val read = file.readText()
- assertEquals(bigText.length, read.length)
- assertEquals(bigText, read)
- }
- }
-
- protected fun assertPathEquals(expected: String, actual: String, message: String? = null) {
- asserter.assertEquals(message, expected.replace("\\", "/"), actual.replace("\\", "/"))
- }
-}
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeTest/kotlin/ByteArrayOpTest.kt b/mirai-core-utils/src/nativeTest/kotlin/ByteArrayOpTest.kt
deleted file mode 100644
index 58c63fdb1..000000000
--- a/mirai-core-utils/src/nativeTest/kotlin/ByteArrayOpTest.kt
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-@file:OptIn(TestOnly::class)
-
-package net.mamoe.mirai.utils
-
-import io.ktor.utils.io.core.*
-import kotlin.test.Test
-import kotlin.test.assertEquals
-
-internal actual class ByteArrayOpTest : CommonByteArrayOpTest() {
-
-
- private fun withZlibBufferSize(size: Long, block: () -> R): R {
- val o = ZLIB_BUFFER_SIZE
- ZLIB_BUFFER_SIZE = size
- try {
- return block()
- } finally {
- ZLIB_BUFFER_SIZE = o
- }
- }
-
- @Test
- fun testDeflateBig() {
- withZlibBufferSize(8192) { // use smaller buffer to check.
- val str = sampleLongText.repeat(8) // 4000+ chars
- println("Input size: ${str.length}")
- println("Deflating")
- println()
- val bytes = str.toByteArray().deflate()
- println()
- println("Deflated, size = ${bytes.size}, content = ${bytes.toUHexString()}")
- println()
- println("Inflating")
- println()
- val inflated = bytes.inflate()
- println()
- println("Inflated, size = ${inflated.size}, content = ${inflated.toUHexString()}")
- println()
- assertEquals(str, inflated.decodeToString())
- }
- }
-
-
- @Test
- fun testInflateBigDataFromJvm() {
- withZlibBufferSize(8192) { // use smaller buffer to check.
- val input =
- "78 9C ED 92 31 8E 1B 31 0C 45 AF C2 2E CD C2 B0 8B 5D 20 65 4A 03 0E B0 57 E0 68 68 0F 61 89 12 44 CA B3 73 FB E5 C8 09 E2 23 A4 50 27 41 E4 E7 E7 D7 BB E4 4A 09 CE 45 5B 02 56 50 4E 25 6E 30 B7 94 36 30 FA 32 C8 57 B0 85 A0 54 16 63 B9 01 CA 0C B6 15 52 B2 7E 67 99 9B 5A DD 0E 70 79 91 5A 50 61 22 92 DE FB B7 E4 87 EB 9B F7 63 9D 5F 27 D0 83 AA 0F 96 40 BD FA F4 7E 3C EA 1B AC 8B 77 A3 40 93 BB E4 55 9E 06 BC D0 72 BE 03 C2 0D 63 A4 AD BB 73 33 DD 95 86 8A 69 8A 34 03 9B 97 41 C2 BB 3F 3C DF B5 50 E0 E4 8A 93 B7 1F E0 6C DD A1 B6 FA E0 87 37 48 F6 45 C5 17 BF FA 15 02 89 B5 CA E4 2E A6 66 80 51 73 77 16 09 8B 2F E3 D2 14 29 58 CD C2 E1 35 8B 37 F0 00 90 65 8F 85 54 5D 85 DD E5 E6 2B 84 05 E5 46 73 1F BC FA E0 92 4B 8B 58 59 77 B3 CF 90 4E 3F 3F 8E 0A 2B DB D2 AF D5 47 A0 D2 BE E0 85 AC FA D1 40 17 22 53 08 59 EC CF 94 D7 C8 0B AA E2 6D 37 BD 87 91 FC C5 45 F6 55 DC 41 97 9D 49 EF 96 0B 94 36 45 D6 65 EF D7 7C B5 15 BD 32 B2 67 F5 2B FA 3F C1 A7 8B FC F6 E8 AA 3B 0B B1 CD 7B 9D FF 90 72 16 ED 76 FE CD 3C 5C 06 3D 83 9E 41 CF A0 67 D0 33 E8 19 F4 0C 7A 06 3D 83 9E 41 CF A0 67 D0 33 E8 19 F4 FC 87 F4 7C 03 ED CB 93 EB"
- .hexToBytes()
- println()
- val bytes = input.inflate()
- println("Inflated, size = ${bytes.size}, content = ${bytes.toUHexString()}")
- println()
- val expected = sampleLongText.repeat(8)
- val actual = bytes.decodeToString()
- println(expected)
- println(actual)
- assertEquals(expected.length, actual.length)
- assertEquals(expected, actual)
- }
- }
-
-}
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeTest/kotlin/CollectionsTest.kt b/mirai-core-utils/src/nativeTest/kotlin/CollectionsTest.kt
deleted file mode 100644
index f31e36291..000000000
--- a/mirai-core-utils/src/nativeTest/kotlin/CollectionsTest.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import kotlin.test.Test
-import kotlin.test.assertEquals
-import kotlin.test.assertFails
-import kotlin.test.assertFalse
-
-internal sealed class MapTest(
- private val map: MutableMap
-) {
- class ConcurrentMapTest : MapTest(ConcurrentHashMap())
-
- @Test
- fun `initial state test`() {
- assertEquals(0, map.size)
- assertEquals(null, map[1])
- assertFalse(map.iterator().hasNext())
- assertFails { map.iterator().next() }
- }
-
- @Test
- fun `get set size`() {
- assertEquals(0, map.size)
- assertEquals(null, map[1])
- map[1] = 2
- assertEquals(2, map[1])
- assertEquals(1, map.size)
- map[2] = 2
- assertEquals(2, map[2])
- assertEquals(2, map.size)
- }
-}
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeTest/kotlin/TimeUtilsTest.kt b/mirai-core-utils/src/nativeTest/kotlin/TimeUtilsTest.kt
deleted file mode 100644
index e356175e4..000000000
--- a/mirai-core-utils/src/nativeTest/kotlin/TimeUtilsTest.kt
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import kotlin.test.Test
-import kotlin.test.assertEquals
-import kotlin.test.assertNotNull
-import kotlin.test.assertTrue
-
-internal class TimeUtilsTest {
-
- @Test
- fun `can get currentTimeMillis`() {
- val time = currentTimeMillis()
- assertTrue(time.toString()) { time > 1654209523269 }
- }
-
- @Test
- fun `can get currentTimeFormatted`() {
- // 2022-28-26 18:28:28
- assertTrue { currentTimeFormatted().matches(Regex("""^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$""")) }
- }
-
- @Test
- fun `can parse explicit timestamp`() {
- val epochMilli = 1681174590123 // 2023-04-11 00:56:30 GMT
- val regex = Regex("""^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$""")
-
- val formatted = regex.find(formatTime(epochMilli, null))
- assertNotNull(formatted)
-
- formatted.groupValues.run {
- assertEquals(get(1), "2023")
- assertEquals(get(2), "04")
- assertTrue { get(3) == "11" || get(3) == "10" }
- assertTrue { get(4).toInt() in 0..23 }
- assertEquals(get(5), "56")
- assertEquals(get(6), "30")
- }
- }
-
- @Test
- fun `can format with custom formatter`() {
- fun formatTimeAndPrint(formatter: String?): String {
- return formatTime(currentTimeMillis(), formatter).also { println("custom formatted time: $it") }
- }
-
- assertTrue {
- formatTimeAndPrint("MmMm").matches(Regex("""^MmMm$"""))
- }
- assertTrue {
- formatTimeAndPrint("MM-mm").matches(Regex("""^\d{2}-\d{2}$"""))
- }
- assertTrue {
- formatTimeAndPrint("yyyyMMddHHmmss").matches(Regex("""^\d{14}$"""))
- }
- assertTrue {
- formatTimeAndPrint("yyyyMMddHHmmSS").matches(Regex("""^\d{12}SS$"""))
- }
- assertTrue {
- formatTimeAndPrint(null).matches(Regex("""^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$"""))
- }
- assertTrue {
- formatTimeAndPrint("yyyy-MM-dd 114514").matches(Regex("""^\d{4}-\d{2}-\d{2} 114514$"""))
- }
- assertTrue {
- formatTimeAndPrint("yyyyMM-114 514--mm-SS").matches(Regex("""^\d{4}\d{2}-114 514--\d{2}-SS$"""))
- }
- assertTrue {
- formatTimeAndPrint("yyyy-MM-dd HH-mm-ss").matches(Regex("""^\d{4}-\d{2}-\d{2} \d{2}-\d{2}-\d{2}$"""))
- }
- assertTrue {
- formatTimeAndPrint("yyyy/MM\\dd HH:mm-ss").matches(Regex("""^\d{4}/\d{2}\\\d{2} \d{2}:\d{2}-\d{2}$"""))
- }
- }
-}
\ No newline at end of file
diff --git a/mirai-core-utils/src/nativeTest/kotlin/package.kt b/mirai-core-utils/src/nativeTest/kotlin/package.kt
deleted file mode 100644
index f699501a9..000000000
--- a/mirai-core-utils/src/nativeTest/kotlin/package.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
\ No newline at end of file
diff --git a/mirai-core-utils/src/unixMain/kotlin/MiraiFileImpl.kt b/mirai-core-utils/src/unixMain/kotlin/MiraiFileImpl.kt
deleted file mode 100644
index 8fdbebe64..000000000
--- a/mirai-core-utils/src/unixMain/kotlin/MiraiFileImpl.kt
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import io.ktor.utils.io.core.*
-import io.ktor.utils.io.errors.*
-import kotlinx.cinterop.*
-import platform.posix.*
-
-private fun readlink(path: String): String = memScoped {
- val len = realpath(path, null)
- if (len != null) {
- try {
- return len.toKString()
- } finally {
- free(len)
- }
- } else {
- when (val errno = errno) {
- ENOTDIR -> return@memScoped path
- EACCES -> return@memScoped path // permission denied
- ENOENT -> return@memScoped path // no such file
- else -> throw IllegalArgumentException(
- "Invalid path($errno): $path",
- cause = PosixException.forErrno(posixFunctionName = "realpath()")
- )
- }
- }
-}
-
-internal actual class MiraiFileImpl actual constructor(
- override val path: String,
-) : MiraiFile {
- actual companion object {
- private const val SEPARATOR = '/'
- private val ROOT by lazy { MiraiFileImpl("/") }
-
- @Suppress("UnnecessaryOptInAnnotation")
- @OptIn(UnsafeNumber::class)
- actual fun getWorkingDir(): MiraiFile {
- val path = memScoped {
- ByteArray(PATH_MAX).usePinned {
- getcwd(it.addressOf(0), it.get().size.convert())
- it.get().toKString()
- }
- }
- return MiraiFile.create(path)
- }
- }
-
- override val absolutePath: String by lazy { kotlin.run { readlink(path) } }
-
- override val parent: MiraiFile? by lazy {
- val absolutePath = absolutePath
- val p = absolutePath.substringBeforeLast(SEPARATOR, "")
- if (p.isEmpty()) {
- if (absolutePath.singleOrNull() == SEPARATOR) return@lazy null // root
- else return@lazy ROOT
- }
- MiraiFileImpl(p)
- }
-
- override val name: String
- get() = absolutePath.substringAfterLast('/', "").ifEmpty { absolutePath }
-
- init {
- absolutePath.split('/').forEach { checkName(it) }
- }
-
- private fun checkName(name: String) {
- name.forEach { c ->
- if (c in """\/:?*"><|""") {
- throw IllegalArgumentException("'${name}' contains illegal character '$c'.")
- }
- }
- }
-
- override val length: Long
- get() = useStat { it.st_size.convert() } ?: 0
-
- @OptIn(UnsafeNumber::class)
- override val isFile: Boolean
- get() = useStat { it.st_mode.convert() flag S_IFREG } ?: false
-
- @OptIn(UnsafeNumber::class)
- override val isDirectory: Boolean
- get() = useStat { it.st_mode.convert() flag S_IFDIR } ?: false
-
- override fun exists(): Boolean = useStat { true } ?: false
-
- override fun resolve(path: String): MiraiFile {
- when (path) {
- "." -> return this
- ".." -> return parent ?: this // root
- }
-
- if (path.startsWith(SEPARATOR)) {
- return MiraiFileImpl(path)
- }
-
- return MiraiFileImpl("$absolutePath/$path")
- }
-
- override fun resolve(file: MiraiFile): MiraiFile {
- val parent = file.parent ?: return resolve(file.name)
- return resolve(parent).resolve(file.name)
- }
-
- override fun createNewFile(): Boolean {
- memScoped {
- val fp = fopen(absolutePath, "w")
- fwrite(fp, 0, 0, fp)
- fclose(fp)
- return true
- }
- }
-
- override fun delete(): Boolean {
- return if (isFile) {
- remove(absolutePath) == 0
- } else {
- rmdir(absolutePath) == 0
- }
- }
-
- override fun mkdir(): Boolean {
- @Suppress("UnnecessaryOptInAnnotation") // bug
- @OptIn(UnsafeNumber::class)
- return (mkdir("$absolutePath/", "755".toUShort(8).convert()).convert() == 0)
- }
-
- @OptIn(UnsafeNumber::class)
- override fun mkdirs(): Boolean {
- val flags = useStat { it.st_mode.convert() }
- return when {
- flags == null -> {
- this.parent?.mkdirs()
- mkdir()
- }
- flags flag S_IFDIR -> {
- false // already exists
- }
- else -> {
- mkdir()
- }
- }
- }
-
- override fun input(): Input {
- val handle = fopen(absolutePath, "rb")
- ?: throw IOException(
- "Failed to open file '$absolutePath'",
- PosixException.forErrno(posixFunctionName = "fopen()")
- )
- return PosixInputForFile(handle)
- }
-
- override fun output(): Output {
- val handle = fopen(absolutePath, "wb")
- ?: throw IOException(
- "Failed to open file '$absolutePath'",
- PosixException.forErrno(posixFunctionName = "fopen()")
- )
- return PosixFileInstanceOutput(handle)
- }
-
- override fun hashCode(): Int {
- return this.path.hashCode()
- }
-
- override fun equals(other: Any?): Boolean {
- if (other == null) return false
- if (!isSameType(this, other)) return false
- return this.path == other.path
- }
-
- override fun toString(): String {
- return "MiraiFileImpl($path)"
- }
-}
\ No newline at end of file
diff --git a/mirai-core-utils/src/unixMain/kotlin/StandardUtils.kt b/mirai-core-utils/src/unixMain/kotlin/StandardUtils.kt
deleted file mode 100644
index 56bf10284..000000000
--- a/mirai-core-utils/src/unixMain/kotlin/StandardUtils.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import kotlinx.cinterop.UnsafeNumber
-import kotlinx.cinterop.convert
-import platform.posix._SC_NPROCESSORS_ONLN
-import platform.posix.sysconf
-
-@OptIn(UnsafeNumber::class)
-public actual fun availableProcessors(): Int = sysconf(_SC_NPROCESSORS_ONLN).convert()
diff --git a/mirai-core-utils/src/unixTest/kotlin/UnixMiraiFileImplTest.kt b/mirai-core-utils/src/unixTest/kotlin/UnixMiraiFileImplTest.kt
deleted file mode 100644
index 41e0ed03e..000000000
--- a/mirai-core-utils/src/unixTest/kotlin/UnixMiraiFileImplTest.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import kotlin.math.absoluteValue
-import kotlin.random.Random
-import kotlin.test.Test
-import kotlin.test.assertEquals
-
-internal class UnixMiraiFileImplTest : AbstractNativeMiraiFileImplTest() {
- private val rand = Random.nextInt().absoluteValue
- override val baseTempDir: MiraiFile by lazy { MiraiFile.create(MiraiFile.getWorkingDir().absolutePath + "/mirai_unit_tests") }
- override val tempPath by lazy { "${baseTempDir.absolutePath}/temp$rand" }
-
- @Test
- override fun parent() {
- assertEquals(baseTempDir.absolutePath, tempDir.parent!!.absolutePath)
- assertEquals(null, MiraiFile.create("/").parent)
- assertEquals("/", MiraiFile.create("/dev").parent?.path)
- assertEquals("/", MiraiFile.create("/dev").parent?.absolutePath)
- super.parent()
- }
-
- @Test
- override fun `canonical paths for non-canonical input`() {
- super.`canonical paths for non-canonical input`()
-
- // extra /sss/..
- MiraiFile.create("$tempPath/sss/..").resolve("test").let {
- assertPathEquals("${tempPath}/sss/../test", it.path) // because file is not found
- assertPathEquals("${tempPath}/sss/../test", it.absolutePath)
- }
- }
-
- @Test
- override fun `resolve absolute`() {
- MiraiFile.create("$tempPath/").resolve("/Users").let {
- assertEquals("/Users", it.path)
- assertEquals("/Users", it.absolutePath)
- }
- }
-}
\ No newline at end of file
diff --git a/mirai-core/build.gradle.kts b/mirai-core/build.gradle.kts
index 1d5057af2..757d2dc8b 100644
--- a/mirai-core/build.gradle.kts
+++ b/mirai-core/build.gradle.kts
@@ -10,8 +10,6 @@
@file:Suppress("UNUSED_VARIABLE")
import BinaryCompatibilityConfigurator.configureBinaryValidators
-import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractNativeLibrary
-import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import shadow.relocateCompileOnly
import shadow.relocateImplementation
@@ -32,8 +30,6 @@ kotlin {
apply(plugin = "explicit-api")
configureJvmTargetsHierarchical("net.mamoe.mirai.internal")
- configureNativeTargetsHierarchical(project)
- configureNativeTargetBinaries(project) // register native binaries for mirai-core only
optInForAllSourceSets("net.mamoe.mirai.utils.MiraiExperimentalApi")
optInForAllSourceSets("net.mamoe.mirai.utils.MiraiInternalApi")
@@ -122,11 +118,6 @@ kotlin {
}
}
- findByName("nativeMain")?.apply {
- dependencies {
- }
- }
-
// Kt bignum
findByName("jvmBaseMain")?.apply {
@@ -150,75 +141,12 @@ kotlin {
relocateImplementation(`ktor-client-core_relocated`)
}
}
- configure(NATIVE_TARGETS.map { getByName(it + "Main") }
- + NATIVE_TARGETS.map { getByName(it + "Test") }) {
- // no relocation in native, include binaries
- dependencies {
- api(`ktor-io`) {
- exclude(ExcludeProperties.`slf4j-api`)
- }
- }
- }
findByName("jvmBaseMain")?.apply {
dependencies {
relocateImplementation(`ktor-client-okhttp_relocated`)
}
}
- configure(WIN_TARGETS.map { getByName(it + "Main") }) {
- dependencies {
- implementation(`ktor-client-curl`)
- }
- }
- configure(LINUX_TARGETS.map { getByName(it + "Main") }) {
- dependencies {
- implementation(`ktor-client-cio`)
- }
- }
- findByName("darwinMain")?.apply {
- dependencies {
- implementation(`ktor-client-darwin`)
- }
- }
-
- // Linkage
- NATIVE_TARGETS.forEach { targetName ->
- val defFile = projectDir.resolve("src/nativeMain/cinterop/OpenSSL.def")
- val target = targets.getByName(targetName) as KotlinNativeTarget
- target.compilations.getByName("main").cinterops.create("OpenSSL")
- .apply {
- this.defFile = defFile
- packageName("openssl")
- }
-
- configure(target.binaries.filterIsInstance()) {
- export(project(":mirai-core-api"))
- export(project(":mirai-core-utils"))
- }
- }
-
- UNIX_LIKE_TARGETS.forEach { target ->
- (targets.getByName(target) as KotlinNativeTarget).compilations.getByName("main").cinterops.create("Socket")
- .apply {
- defFile = projectDir.resolve("src/unixMain/cinterop/Socket.def")
- packageName("sockets")
- }
- }
-
- WIN_TARGETS.forEach { target ->
- (targets.getByName(target) as KotlinNativeTarget).compilations.getByName("main").cinterops.create("Socket")
- .apply {
- defFile = projectDir.resolve("src/mingwX64Main/cinterop/Socket.def")
- packageName("sockets")
- }
- }
-
- disableCrossCompile()
-// val unixMain by getting {
-// dependencies {
-// implementation(`ktor-client-cio`)
-// }
-// }
}
}
@@ -226,28 +154,6 @@ atomicfu {
transformJvm = false
}
-afterEvaluate {
- val main = projectDir.resolve("src/nativeTest/kotlin/local/TestMain.kt")
- if (!main.exists()) {
- main.writeText(
- """
- /*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
- package net.mamoe.mirai.internal.local
-
- fun main() {}
- """.trimIndent()
- )
- }
-}
-
if (tasks.findByName("androidMainClasses") != null) {
tasks.register("checkAndroidApiLevel") {
doFirst {
diff --git a/mirai-core/src/commonMain/kotlin/network/components/QRCodeLoginProcessor.kt b/mirai-core/src/commonMain/kotlin/network/components/QRCodeLoginProcessor.kt
index da11eae22..a3ded7fb6 100644
--- a/mirai-core/src/commonMain/kotlin/network/components/QRCodeLoginProcessor.kt
+++ b/mirai-core/src/commonMain/kotlin/network/components/QRCodeLoginProcessor.kt
@@ -84,7 +84,6 @@ internal class QRCodeLoginProcessorImpl(
margin = qrCodeLoginListener.qrCodeMargin,
ecLevel = qrCodeLoginListener.qrCodeEcLevel,
),
- attempts = 1
)
check(resp is WtLogin.TransEmp.Response.FetchQRCode) { "Cannot fetch qrcode, resp=$resp" }
qrCodeLoginListener.onFetchQRCode(handler.context.bot, resp.imageData)
diff --git a/mirai-core/src/commonTest/kotlin/test/NativeTestWrapper.kt b/mirai-core/src/commonTest/kotlin/test/NativeTestWrapper.kt
deleted file mode 100644
index 2d29a7dac..000000000
--- a/mirai-core/src/commonTest/kotlin/test/NativeTestWrapper.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-@file:JvmName("NativeTestWrapperKt")
-
-package net.mamoe.mirai.internal.test
-
-import kotlin.jvm.JvmName
-import kotlin.test.Test
-
-internal class NativeTestWrapper {
- @Test
- fun test() {
- startNativeTestIfNeeded()
- }
-}
-
-internal expect fun startNativeTestIfNeeded()
\ No newline at end of file
diff --git a/mirai-core/src/commonTest/kotlin/testFramework/Platform.kt b/mirai-core/src/commonTest/kotlin/testFramework/Platform.kt
index 843faa39f..ed5524966 100644
--- a/mirai-core/src/commonTest/kotlin/testFramework/Platform.kt
+++ b/mirai-core/src/commonTest/kotlin/testFramework/Platform.kt
@@ -15,7 +15,6 @@ expect fun currentPlatform(): Platform
enum class PlatformRuntime {
JVM,
DALVIK,
- NATIVE,
}
// see `@DisabledOnPlatform`
@@ -33,19 +32,5 @@ sealed class Platform(
object AndroidInstrumentedTest : Android(PlatformRuntime.DALVIK)
object Jvm : JvmLike(PlatformRuntime.JVM)
-
- sealed class Native : Platform(PlatformRuntime.NATIVE)
-
- sealed class Windows : Native()
- object MingwX64 : Windows()
-
- sealed class UnixLike : Native()
-
- sealed class Linux : UnixLike()
- object LinuxX64 : Linux()
-
- sealed class Macos : UnixLike()
- object MacosX64 : Macos()
- object MacosArm64 : Macos()
}
diff --git a/mirai-core/src/darwinMain/kotlin/MiraiImpl.kt b/mirai-core/src/darwinMain/kotlin/MiraiImpl.kt
deleted file mode 100644
index 07f8cd43a..000000000
--- a/mirai-core/src/darwinMain/kotlin/MiraiImpl.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal
-
-import io.ktor.client.*
-import io.ktor.client.engine.darwin.*
-import io.ktor.client.plugins.*
-
-internal actual fun createDefaultHttpClient(): HttpClient {
- return HttpClient(Darwin) {
- install(HttpTimeout) {
- this.requestTimeoutMillis = 30_0000
- this.connectTimeoutMillis = 30_0000
- this.socketTimeoutMillis = 30_0000
- }
- }
-}
diff --git a/mirai-core/src/darwinMain/kotlin/package.kt b/mirai-core/src/darwinMain/kotlin/package.kt
deleted file mode 100644
index 7df5cebc4..000000000
--- a/mirai-core/src/darwinMain/kotlin/package.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal
\ No newline at end of file
diff --git a/mirai-core/src/darwinTest/kotlin/package.kt b/mirai-core/src/darwinTest/kotlin/package.kt
deleted file mode 100644
index 7df5cebc4..000000000
--- a/mirai-core/src/darwinTest/kotlin/package.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal
\ No newline at end of file
diff --git a/mirai-core/src/jvmBaseTest/kotlin/test/NativeTestWrapper.kt b/mirai-core/src/jvmBaseTest/kotlin/test/NativeTestWrapper.kt
index a448d7241..e5eb9da80 100644
--- a/mirai-core/src/jvmBaseTest/kotlin/test/NativeTestWrapper.kt
+++ b/mirai-core/src/jvmBaseTest/kotlin/test/NativeTestWrapper.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
+ * Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -9,4 +9,3 @@
package net.mamoe.mirai.internal.test
-internal actual fun startNativeTestIfNeeded() {}
\ No newline at end of file
diff --git a/mirai-core/src/linuxX64Main/kotlin/MiraiImpl.kt b/mirai-core/src/linuxX64Main/kotlin/MiraiImpl.kt
deleted file mode 100644
index 841be8763..000000000
--- a/mirai-core/src/linuxX64Main/kotlin/MiraiImpl.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal
-
-import io.ktor.client.*
-import io.ktor.client.engine.cio.*
-import io.ktor.client.plugins.*
-
-internal actual fun createDefaultHttpClient(): HttpClient {
- return HttpClient(CIO) {
- install(HttpTimeout) {
- this.requestTimeoutMillis = 30_0000
- this.connectTimeoutMillis = 30_0000
- this.socketTimeoutMillis = 30_0000
- }
- }
-}
diff --git a/mirai-core/src/linuxX64Main/kotlin/package.kt b/mirai-core/src/linuxX64Main/kotlin/package.kt
deleted file mode 100644
index 7df5cebc4..000000000
--- a/mirai-core/src/linuxX64Main/kotlin/package.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal
\ No newline at end of file
diff --git a/mirai-core/src/linuxX64Test/kotlin/package.kt b/mirai-core/src/linuxX64Test/kotlin/package.kt
deleted file mode 100644
index 7df5cebc4..000000000
--- a/mirai-core/src/linuxX64Test/kotlin/package.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal
\ No newline at end of file
diff --git a/mirai-core/src/linuxX64Test/kotlin/testFramework/currentPlatform.kt b/mirai-core/src/linuxX64Test/kotlin/testFramework/currentPlatform.kt
deleted file mode 100644
index 20fc1db67..000000000
--- a/mirai-core/src/linuxX64Test/kotlin/testFramework/currentPlatform.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.testFramework
-
-actual fun currentPlatform(): Platform = Platform.LinuxX64
\ No newline at end of file
diff --git a/mirai-core/src/macosArm64Test/kotlin/package.kt b/mirai-core/src/macosArm64Test/kotlin/package.kt
deleted file mode 100644
index 20b5b6a1b..000000000
--- a/mirai-core/src/macosArm64Test/kotlin/package.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal
\ No newline at end of file
diff --git a/mirai-core/src/macosArm64Test/kotlin/testFramework/currentPlatform.kt b/mirai-core/src/macosArm64Test/kotlin/testFramework/currentPlatform.kt
deleted file mode 100644
index 1f61af5f3..000000000
--- a/mirai-core/src/macosArm64Test/kotlin/testFramework/currentPlatform.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.testFramework
-
-actual fun currentPlatform(): Platform = Platform.MacosArm64
\ No newline at end of file
diff --git a/mirai-core/src/macosX64Test/kotlin/package.kt b/mirai-core/src/macosX64Test/kotlin/package.kt
deleted file mode 100644
index a56b88234..000000000
--- a/mirai-core/src/macosX64Test/kotlin/package.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal
diff --git a/mirai-core/src/macosX64Test/kotlin/testFramework/currentPlatform.kt b/mirai-core/src/macosX64Test/kotlin/testFramework/currentPlatform.kt
deleted file mode 100644
index 62ef384b5..000000000
--- a/mirai-core/src/macosX64Test/kotlin/testFramework/currentPlatform.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.testFramework
-
-actual fun currentPlatform(): Platform = Platform.MacosX64
\ No newline at end of file
diff --git a/mirai-core/src/mingwX64Main/cinterop/Socket.def b/mirai-core/src/mingwX64Main/cinterop/Socket.def
deleted file mode 100644
index debd8e44c..000000000
--- a/mirai-core/src/mingwX64Main/cinterop/Socket.def
+++ /dev/null
@@ -1,38 +0,0 @@
-headers = winsock.h
-
----
-#define WIN32_LEAN_AND_MEAN
-#include
-#include
-#include
-#include
-#include
-
-static SOCKET socket_create_connect(char *host, unsigned short port) {
- SOCKADDR_STORAGE local_addr = {0};
- SOCKADDR_STORAGE remote_addr = {0};
- DWORD local_addr_size = sizeof(local_addr);
- DWORD remote_addr_size = sizeof(remote_addr);
- char port_name[6];
- int sockfd;
-
- sprintf(port_name, "%d", (int)port);
-
- if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) == INVALID_SOCKET) {
- if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
- return INVALID_SOCKET;
- }
- } else {
- int ipv6only = 0;
- setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only));
- }
- if (!WSAConnectByNameA(sockfd, host, port_name, &local_addr_size, (SOCKADDR*)&local_addr, &remote_addr_size, (SOCKADDR*)&remote_addr, NULL, NULL)) {
- closesocket(sockfd);
- return INVALID_SOCKET;
- }
- if (setsockopt(sockfd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0) == SOCKET_ERROR) {
- closesocket(sockfd);
- return INVALID_SOCKET;
- }
- return sockfd;
-}
\ No newline at end of file
diff --git a/mirai-core/src/mingwX64Main/kotlin/MiraiImpl.kt b/mirai-core/src/mingwX64Main/kotlin/MiraiImpl.kt
deleted file mode 100644
index 62a9aa7db..000000000
--- a/mirai-core/src/mingwX64Main/kotlin/MiraiImpl.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal
-
-import io.ktor.client.*
-import io.ktor.client.engine.curl.*
-import io.ktor.client.plugins.*
-
-internal actual fun createDefaultHttpClient(): HttpClient {
- return HttpClient(Curl) {
- install(HttpTimeout) {
- this.requestTimeoutMillis = 30_0000
- this.connectTimeoutMillis = 30_0000
- this.socketTimeoutMillis = 30_0000
- }
- }
-}
diff --git a/mirai-core/src/mingwX64Main/kotlin/package.kt b/mirai-core/src/mingwX64Main/kotlin/package.kt
deleted file mode 100644
index 7df5cebc4..000000000
--- a/mirai-core/src/mingwX64Main/kotlin/package.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal
\ No newline at end of file
diff --git a/mirai-core/src/mingwX64Main/kotlin/utils/PlatformSocket.kt b/mirai-core/src/mingwX64Main/kotlin/utils/PlatformSocket.kt
deleted file mode 100644
index c58420297..000000000
--- a/mirai-core/src/mingwX64Main/kotlin/utils/PlatformSocket.kt
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.utils
-
-import io.ktor.utils.io.core.*
-import io.ktor.utils.io.core.EOFException
-import io.ktor.utils.io.errors.*
-import kotlinx.cinterop.*
-import kotlinx.coroutines.*
-import kotlinx.coroutines.sync.Mutex
-import kotlinx.coroutines.sync.withLock
-import net.mamoe.mirai.internal.network.highway.HighwayProtocolChannel
-import net.mamoe.mirai.utils.ByteArrayPool
-import net.mamoe.mirai.utils.DEFAULT_BUFFER_SIZE
-import net.mamoe.mirai.utils.toReadPacket
-import platform.posix.*
-import kotlin.contracts.InvocationKind
-import kotlin.contracts.contract
-
-/**
- * TCP Socket.
- */
-internal actual class PlatformSocket(
- private val socket: SOCKET
-) : Closeable, HighwayProtocolChannel {
- @Suppress("UnnecessaryOptInAnnotation")
- @OptIn(ExperimentalCoroutinesApi::class, DelicateCoroutinesApi::class)
- private val readDispatcher: CoroutineDispatcher = newSingleThreadContext("PlatformSocket#$socket.readDispatcher")
-
- @Suppress("UnnecessaryOptInAnnotation")
- @OptIn(ExperimentalCoroutinesApi::class, DelicateCoroutinesApi::class)
- private val sendDispatcher: CoroutineDispatcher = newSingleThreadContext("PlatformSocket#$socket.sendDispatcher")
-
- private val writeLock = Mutex()
- private val writeBuffer = ByteArray(DEFAULT_BUFFER_SIZE).pin()
-
- actual val isOpen: Boolean
- get() = send(socket, null, 0, 0).convert() != 0L
-
- actual override fun close() {
- closesocket(socket)
- (readDispatcher as? CloseableCoroutineDispatcher)?.close()
- (sendDispatcher as? CloseableCoroutineDispatcher)?.close()
- writeBuffer.unpin()
- }
-
- actual suspend fun send(packet: ByteArray, offset: Int, length: Int): Unit = writeLock.withLock {
- withContext(sendDispatcher) {
- require(offset >= 0) { "offset must >= 0" }
- require(length >= 0) { "length must >= 0" }
- require(offset + length <= packet.size) { "It must follows offset + length <= packet.size" }
- packet.usePinned { pin ->
- if (send(socket, pin.addressOf(offset), length.convert(), 0).convert() < 0L) {
- @Suppress("INVISIBLE_MEMBER")
- throw PosixException.forErrno(posixFunctionName = "send()").wrapIO()
- }
- }
- }
- }
-
-
- actual override suspend fun send(packet: ByteReadPacket): Unit = writeLock.withLock {
- withContext(sendDispatcher) {
- val writeBuffer = writeBuffer
- while (packet.remaining != 0L) {
- val length = packet.readAvailable(writeBuffer.get())
- if (send(socket, writeBuffer.addressOf(0), length.convert(), 0).convert() < 0L) {
- @Suppress("INVISIBLE_MEMBER")
- throw PosixException.forErrno(posixFunctionName = "send()").wrapIO()
- }
- }
- }
- }
-
- /**
- * @throws EOFException
- */
- actual override suspend fun read(): ByteReadPacket = withContext(readDispatcher) {
- val readBuffer = ByteArrayPool.borrow()
- try {
- val length = readBuffer.usePinned { pinned ->
- recv(socket, pinned.addressOf(0), pinned.get().size.convert(), 0).convert()
- }
- if (length <= 0L) throw EOFException("recv: $length, errno=$errno")
- // [toReadPacket] 后的 readBuffer 会被其内部直接使用,而不是 copy 一份
- // 在 release 前不能被复用
- readBuffer.toReadPacket(length = length.toInt()) { ByteArrayPool.recycle(it) }
- } catch (e: Throwable) {
- ByteArrayPool.recycle(readBuffer)
- throw e
- }
- }
-
- actual companion object {
-
- actual suspend fun connect(
- serverIp: String,
- serverPort: Int
- ): PlatformSocket {
- val r = sockets.socket_create_connect(serverIp.cstr, serverPort.toUShort())
- if (r == INVALID_SOCKET) error("Failed socket_create_connect: $r")
- return PlatformSocket(r)
- }
-
- actual suspend inline fun withConnection(
- serverIp: String,
- serverPort: Int,
- block: PlatformSocket.() -> R
- ): R {
- contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
- return connect(serverIp, serverPort).use(block)
- }
- }
-
-}
diff --git a/mirai-core/src/mingwX64Test/kotlin/package.kt b/mirai-core/src/mingwX64Test/kotlin/package.kt
deleted file mode 100644
index a56b88234..000000000
--- a/mirai-core/src/mingwX64Test/kotlin/package.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal
diff --git a/mirai-core/src/mingwX64Test/kotlin/testFramework/currentPlatform.kt b/mirai-core/src/mingwX64Test/kotlin/testFramework/currentPlatform.kt
deleted file mode 100644
index e685766e3..000000000
--- a/mirai-core/src/mingwX64Test/kotlin/testFramework/currentPlatform.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.testFramework
-
-actual fun currentPlatform(): Platform = Platform.MingwX64
\ No newline at end of file
diff --git a/mirai-core/src/nativeMain/cinterop/OpenSSL.def b/mirai-core/src/nativeMain/cinterop/OpenSSL.def
deleted file mode 100644
index bdadd3671..000000000
--- a/mirai-core/src/nativeMain/cinterop/OpenSSL.def
+++ /dev/null
@@ -1,73 +0,0 @@
-headers = openssl/ec.h \
- openssl/ecdh.h \
- openssl/evp.h \
- openssl/rsa.h \
- openssl/pem.h \
- openssl/x509.h \
- openssl/err.h
-
-# -L/usr/local/opt/openssl@1.1/1.1.1o/lib is for GitHub actions. See https://github.com/actions/virtual-environments/blob/main/images/macos/macos-12-Readme.md
-
-# For GitHub Actions macos-12 20223-4-15:
-#find: /Library/Application Support/Apple/ParentalControls/Users: Permission denied
-#/usr/local/Cellar/openssl@3/3.1.0/include/openssl/ecdh.h
-#find: /Library/Application Support/Apple/AssetCache/Data: Permission denied
-#/usr/local/Cellar/openssl@1.1/1.1.1t/include/openssl/ecdh.h
-##find: /Library/Application Support/Apple/Remote Desktop/Task Server: Permission denied
-#/usr/local/miniconda/include/openssl/ecdh.h
-#/usr/local/miniconda/pkgs/openssl-1.1.1s-hca72f7f_0/include/openssl/ecdh.h
-
-linkerOpts = -lcrypto \
- -lssl \
- -L/opt/openssl/lib64 \
- -L/opt/openssl/lib \
- -L/usr/local/opt/openssl@1.1/1.1.1o/lib \
- -L/usr/local/Cellar/openssl@3/3.1.0/lib \
- -L/usr/lib/openssl@1.1/1.1.1o/lib \
- -L/opt/homebrew/Cellar/openssl@1.1/1.1.1o/lib \
- -L/opt/homebrew/Cellar/openssl@3/3.0.3/lib \
- -L/opt/homebrew/opt/openssl@3/lib \
- -L/usr/local/miniconda/lib \
- -L/usr/lib/ \
- -LC:/openssl/lib \
- -LC:/vcpkg/installed/x64-windows/lib \
- -L/usr/lib64 \
- -L/usr/lib/x86_64-linux-gnu \
- -L/opt/local/lib \
- -L/usr/local/opt/curl/lib \
- -L/opt/homebrew/opt/curl/lib
-
-
-compilerOpts = -I/opt/openssl/include \
- -I/usr/local/include/openssl@3 \
- -I/usr/local/opt/openssl@1.1/1.1.1o/include \
- -I/usr/local/Cellar/openssl@3/3.1.0/include \
- -I/opt/homebrew/Cellar/openssl@1.1/1.1.1o/include \
- -I/opt/homebrew/Cellar/openssl@3/3.0.3/include \
- -I/usr/include/openssl@3 \
- -I/opt/homebrew/opt/openssl@3/include \
- -I/usr/local/miniconda/include \
- -I/usr/include/ \
- -I/usr/include/x86_64-linux-gnu/ \
- -I/usr/local/include/ \
- -IC:/openssl/include/ \
- -IC:/vcpkg/installed/x64-windows/include \
-
----
-
-#include
-#include
-
-static int _evpCipherCtxGetBlockSize(const EVP_CIPHER_CTX *ctx) {
-#ifdef EVP_CIPHER_CTX_block_size
- return EVP_CIPHER_CTX_get_block_size(ctx);
-#endif
- return EVP_CIPHER_CTX_block_size(ctx);
-}
-
-static int _evpPkeyCtxSetRSAKeygenBits(EVP_PKEY_CTX *ctx, int bits) {
-#ifdef EVP_PKEY_CTX_set_rsa_keygen_bits
- return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL);
-#endif
- return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits);
-}
\ No newline at end of file
diff --git a/mirai-core/src/nativeMain/kotlin/MiraiImpl.kt b/mirai-core/src/nativeMain/kotlin/MiraiImpl.kt
deleted file mode 100644
index 70de74f4a..000000000
--- a/mirai-core/src/nativeMain/kotlin/MiraiImpl.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal
-
-import kotlinx.atomicfu.atomic
-import net.mamoe.mirai.internal.message.protocol.MessageProtocolFacade
-import net.mamoe.mirai.internal.utils.MiraiCoreServices
-
-
-/**
- * 初始化 Mirai Native 平台. 必须先调用此 API, 其他 API 才能正常工作.
- */
-@CName("mirai_init")
-public fun initMirai() {
- initRuntimeIfNeeded()
- _MiraiImpl_static_init()
-}
-
-
-private val initialized = atomic(false)
-
-@Suppress("FunctionName")
-internal actual fun _MiraiImpl_static_init() {
- if (!initialized.compareAndSet(expect = false, update = true)) return
- MiraiCoreServices.registerAll()
- MessageProtocolFacade.INSTANCE // register serializers
-}
diff --git a/mirai-core/src/nativeMain/kotlin/contact/GroupImpl.kt b/mirai-core/src/nativeMain/kotlin/contact/GroupImpl.kt
deleted file mode 100644
index 40246af70..000000000
--- a/mirai-core/src/nativeMain/kotlin/contact/GroupImpl.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.contact
-
-import net.mamoe.mirai.contact.ContactList
-import net.mamoe.mirai.contact.Group
-import net.mamoe.mirai.data.GroupInfo
-import net.mamoe.mirai.internal.QQAndroidBot
-import kotlin.coroutines.CoroutineContext
-
-internal actual class GroupImpl actual constructor(
- bot: QQAndroidBot,
- parentCoroutineContext: CoroutineContext,
- id: Long,
- groupInfo: GroupInfo,
- members: ContactList,
-) : Group, CommonGroupImpl(bot, parentCoroutineContext, id, groupInfo, members) {
- actual companion object
-}
\ No newline at end of file
diff --git a/mirai-core/src/nativeMain/kotlin/contact/active/GroupActiveImpl.kt b/mirai-core/src/nativeMain/kotlin/contact/active/GroupActiveImpl.kt
deleted file mode 100644
index e496c3aac..000000000
--- a/mirai-core/src/nativeMain/kotlin/contact/active/GroupActiveImpl.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.contact.active
-
-import net.mamoe.mirai.data.GroupInfo
-import net.mamoe.mirai.internal.contact.GroupImpl
-import net.mamoe.mirai.utils.MiraiLogger
-
-internal actual class GroupActiveImpl actual constructor(
- group: GroupImpl,
- logger: MiraiLogger,
- groupInfo: GroupInfo,
-) : CommonGroupActiveImpl(group, logger, groupInfo)
\ No newline at end of file
diff --git a/mirai-core/src/nativeMain/kotlin/contact/file/AbsoluteFolderImpl.kt b/mirai-core/src/nativeMain/kotlin/contact/file/AbsoluteFolderImpl.kt
deleted file mode 100644
index 8088e2c0b..000000000
--- a/mirai-core/src/nativeMain/kotlin/contact/file/AbsoluteFolderImpl.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.contact.file
-
-import net.mamoe.mirai.contact.FileSupported
-import net.mamoe.mirai.contact.file.AbsoluteFolder
-
-internal actual class AbsoluteFolderImpl actual constructor(
- contact: FileSupported,
- parent: AbsoluteFolder?,
- id: String,
- name: String,
- uploadTime: Long,
- uploaderId: Long,
- lastModifiedTime: Long,
- contentsCount: Int
-) : CommonAbsoluteFolderImpl(contact, parent, id, name, uploadTime, uploaderId, lastModifiedTime, contentsCount)
\ No newline at end of file
diff --git a/mirai-core/src/nativeMain/kotlin/message/protocol/impl/getEmojiPatternResource.kt b/mirai-core/src/nativeMain/kotlin/message/protocol/impl/getEmojiPatternResource.kt
deleted file mode 100644
index 8c3766f13..000000000
--- a/mirai-core/src/nativeMain/kotlin/message/protocol/impl/getEmojiPatternResource.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.message.protocol.impl
-
-internal actual fun getEmojiPatternResourceOrNull(): String? {
- return """\x{1F3F4}\x{E0067}\x{E0062}(?:\x{E0077}\x{E006C}\x{E0073}|\x{E0073}\x{E0063}\x{E0074}|\x{E0065}\x{E006E}\x{E0067})\x{E007F}|(?:\x{1F9D1}\x{1F3FF}\x{200D}\x{2764}(?:\x{FE0F}\x{200D}(?:\x{1F48B}\x{200D})?|\x{200D}(?:\x{1F48B}\x{200D})?)\x{1F9D1}|\x{1F469}\x{1F3FF}\x{200D}\x{1F91D}\x{200D}[\x{1F468}\x{1F469}]|\x{1FAF1}\x{1F3FF}\x{200D}\x{1FAF2})[\x{1F3FB}-\x{1F3FE}]|(?:\x{1F9D1}\x{1F3FE}\x{200D}\x{2764}(?:\x{FE0F}\x{200D}(?:\x{1F48B}\x{200D})?|\x{200D}(?:\x{1F48B}\x{200D})?)\x{1F9D1}|\x{1F469}\x{1F3FE}\x{200D}\x{1F91D}\x{200D}[\x{1F468}\x{1F469}]|\x{1FAF1}\x{1F3FE}\x{200D}\x{1FAF2})[\x{1F3FB}-\x{1F3FD}\x{1F3FF}]|(?:\x{1F9D1}\x{1F3FD}\x{200D}\x{2764}(?:\x{FE0F}\x{200D}(?:\x{1F48B}\x{200D})?|\x{200D}(?:\x{1F48B}\x{200D})?)\x{1F9D1}|\x{1F469}\x{1F3FD}\x{200D}\x{1F91D}\x{200D}[\x{1F468}\x{1F469}]|\x{1FAF1}\x{1F3FD}\x{200D}\x{1FAF2})[\x{1F3FB}\x{1F3FC}\x{1F3FE}\x{1F3FF}]|(?:\x{1F9D1}\x{1F3FC}\x{200D}\x{2764}(?:\x{FE0F}\x{200D}(?:\x{1F48B}\x{200D})?|\x{200D}(?:\x{1F48B}\x{200D})?)\x{1F9D1}|\x{1F469}\x{1F3FC}\x{200D}\x{1F91D}\x{200D}[\x{1F468}\x{1F469}]|\x{1FAF1}\x{1F3FC}\x{200D}\x{1FAF2})[\x{1F3FB}\x{1F3FD}-\x{1F3FF}]|(?:\x{1F9D1}\x{1F3FB}\x{200D}\x{2764}(?:\x{FE0F}\x{200D}(?:\x{1F48B}\x{200D})?|\x{200D}(?:\x{1F48B}\x{200D})?)\x{1F9D1}|\x{1F469}\x{1F3FB}\x{200D}\x{1F91D}\x{200D}[\x{1F468}\x{1F469}]|\x{1FAF1}\x{1F3FB}\x{200D}\x{1FAF2})[\x{1F3FC}-\x{1F3FF}]|\x{1F468}(?:\x{1F3FB}(?:\x{200D}(?:\x{2764}(?:\x{FE0F}\x{200D}(?:\x{1F48B}\x{200D}\x{1F468}[\x{1F3FB}-\x{1F3FF}]|\x{1F468}[\x{1F3FB}-\x{1F3FF}])|\x{200D}(?:\x{1F48B}\x{200D}\x{1F468}[\x{1F3FB}-\x{1F3FF}]|\x{1F468}[\x{1F3FB}-\x{1F3FF}]))|\x{1F91D}\x{200D}\x{1F468}[\x{1F3FC}-\x{1F3FF}]|[\x{2695}\x{2696}\x{2708}]\x{FE0F}|[\x{2695}\x{2696}\x{2708}]|[\x{1F33E}\x{1F373}\x{1F37C}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}]))?|[\x{1F3FC}-\x{1F3FF}]\x{200D}\x{2764}(?:\x{FE0F}\x{200D}(?:\x{1F48B}\x{200D}\x{1F468}[\x{1F3FB}-\x{1F3FF}]|\x{1F468}[\x{1F3FB}-\x{1F3FF}])|\x{200D}(?:\x{1F48B}\x{200D}\x{1F468}[\x{1F3FB}-\x{1F3FF}]|\x{1F468}[\x{1F3FB}-\x{1F3FF}]))|\x{200D}(?:\x{2764}(?:\x{FE0F}\x{200D}(?:\x{1F48B}\x{200D})?|\x{200D}(?:\x{1F48B}\x{200D})?)\x{1F468}|[\x{1F468}\x{1F469}]\x{200D}(?:\x{1F466}\x{200D}\x{1F466}|\x{1F467}\x{200D}[\x{1F466}\x{1F467}])|\x{1F466}\x{200D}\x{1F466}|\x{1F467}\x{200D}[\x{1F466}\x{1F467}]|[\x{1F33E}\x{1F373}\x{1F37C}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}])|\x{1F3FF}\x{200D}(?:\x{1F91D}\x{200D}\x{1F468}[\x{1F3FB}-\x{1F3FE}]|[\x{1F33E}\x{1F373}\x{1F37C}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}])|\x{1F3FE}\x{200D}(?:\x{1F91D}\x{200D}\x{1F468}[\x{1F3FB}-\x{1F3FD}\x{1F3FF}]|[\x{1F33E}\x{1F373}\x{1F37C}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}])|\x{1F3FD}\x{200D}(?:\x{1F91D}\x{200D}\x{1F468}[\x{1F3FB}\x{1F3FC}\x{1F3FE}\x{1F3FF}]|[\x{1F33E}\x{1F373}\x{1F37C}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}])|\x{1F3FC}\x{200D}(?:\x{1F91D}\x{200D}\x{1F468}[\x{1F3FB}\x{1F3FD}-\x{1F3FF}]|[\x{1F33E}\x{1F373}\x{1F37C}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}])|(?:\x{1F3FF}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FE}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FD}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FC}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{200D}[\x{2695}\x{2696}\x{2708}])\x{FE0F}|\x{200D}(?:[\x{1F468}\x{1F469}]\x{200D}[\x{1F466}\x{1F467}]|[\x{1F466}\x{1F467}])|\x{1F3FF}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FE}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FD}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FC}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FF}|\x{1F3FE}|\x{1F3FD}|\x{1F3FC}|\x{200D}[\x{2695}\x{2696}\x{2708}])?|(?:\x{1F469}(?:\x{1F3FB}\x{200D}\x{2764}(?:\x{FE0F}\x{200D}(?:\x{1F48B}\x{200D}[\x{1F468}\x{1F469}]|[\x{1F468}\x{1F469}])|\x{200D}(?:\x{1F48B}\x{200D}[\x{1F468}\x{1F469}]|[\x{1F468}\x{1F469}]))|[\x{1F3FC}-\x{1F3FF}]\x{200D}\x{2764}(?:\x{FE0F}\x{200D}(?:\x{1F48B}\x{200D}[\x{1F468}\x{1F469}]|[\x{1F468}\x{1F469}])|\x{200D}(?:\x{1F48B}\x{200D}[\x{1F468}\x{1F469}]|[\x{1F468}\x{1F469}])))|\x{1F9D1}[\x{1F3FB}-\x{1F3FF}]\x{200D}\x{1F91D}\x{200D}\x{1F9D1})[\x{1F3FB}-\x{1F3FF}]|\x{1F469}\x{200D}\x{1F469}\x{200D}(?:\x{1F466}\x{200D}\x{1F466}|\x{1F467}\x{200D}[\x{1F466}\x{1F467}])|\x{1F469}(?:\x{200D}(?:\x{2764}(?:\x{FE0F}\x{200D}(?:\x{1F48B}\x{200D}[\x{1F468}\x{1F469}]|[\x{1F468}\x{1F469}])|\x{200D}(?:\x{1F48B}\x{200D}[\x{1F468}\x{1F469}]|[\x{1F468}\x{1F469}]))|[\x{1F33E}\x{1F373}\x{1F37C}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}])|\x{1F3FF}\x{200D}[\x{1F33E}\x{1F373}\x{1F37C}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}]|\x{1F3FE}\x{200D}[\x{1F33E}\x{1F373}\x{1F37C}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}]|\x{1F3FD}\x{200D}[\x{1F33E}\x{1F373}\x{1F37C}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}]|\x{1F3FC}\x{200D}[\x{1F33E}\x{1F373}\x{1F37C}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}]|\x{1F3FB}\x{200D}[\x{1F33E}\x{1F373}\x{1F37C}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}])|\x{1F9D1}(?:\x{200D}(?:\x{1F91D}\x{200D}\x{1F9D1}|[\x{1F33E}\x{1F373}\x{1F37C}\x{1F384}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}])|\x{1F3FF}\x{200D}[\x{1F33E}\x{1F373}\x{1F37C}\x{1F384}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}]|\x{1F3FE}\x{200D}[\x{1F33E}\x{1F373}\x{1F37C}\x{1F384}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}]|\x{1F3FD}\x{200D}[\x{1F33E}\x{1F373}\x{1F37C}\x{1F384}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}]|\x{1F3FC}\x{200D}[\x{1F33E}\x{1F373}\x{1F37C}\x{1F384}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}]|\x{1F3FB}\x{200D}[\x{1F33E}\x{1F373}\x{1F37C}\x{1F384}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}\x{1F9AF}-\x{1F9B3}\x{1F9BC}\x{1F9BD}])|\x{1F469}\x{200D}\x{1F466}\x{200D}\x{1F466}|\x{1F469}\x{200D}\x{1F469}\x{200D}[\x{1F466}\x{1F467}]|\x{1F469}\x{200D}\x{1F467}\x{200D}[\x{1F466}\x{1F467}]|(?:\x{1F441}\x{FE0F}?\x{200D}\x{1F5E8}|\x{1F9D1}(?:\x{1F3FF}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FE}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FD}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FC}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FB}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{200D}[\x{2695}\x{2696}\x{2708}])|\x{1F469}(?:\x{1F3FF}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FE}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FD}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FC}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FB}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{200D}[\x{2695}\x{2696}\x{2708}])|\x{1F636}\x{200D}\x{1F32B}|\x{1F3F3}\x{FE0F}?\x{200D}\x{26A7}|\x{1F43B}\x{200D}\x{2744}|(?:[\x{1F3C3}\x{1F3C4}\x{1F3CA}\x{1F46E}\x{1F470}\x{1F471}\x{1F473}\x{1F477}\x{1F481}\x{1F482}\x{1F486}\x{1F487}\x{1F645}-\x{1F647}\x{1F64B}\x{1F64D}\x{1F64E}\x{1F6A3}\x{1F6B4}-\x{1F6B6}\x{1F926}\x{1F935}\x{1F937}-\x{1F939}\x{1F93D}\x{1F93E}\x{1F9B8}\x{1F9B9}\x{1F9CD}-\x{1F9CF}\x{1F9D4}\x{1F9D6}-\x{1F9DD}][\x{1F3FB}-\x{1F3FF}]|[\x{1F46F}\x{1F9DE}\x{1F9DF}])\x{200D}[\x{2640}\x{2642}]|[\x{26F9}\x{1F3CB}\x{1F3CC}\x{1F575}](?:[\x{FE0F}\x{1F3FB}-\x{1F3FF}]\x{200D}[\x{2640}\x{2642}]|\x{200D}[\x{2640}\x{2642}])|\x{1F3F4}\x{200D}\x{2620}|[\x{1F3C3}\x{1F3C4}\x{1F3CA}\x{1F46E}\x{1F470}\x{1F471}\x{1F473}\x{1F477}\x{1F481}\x{1F482}\x{1F486}\x{1F487}\x{1F645}-\x{1F647}\x{1F64B}\x{1F64D}\x{1F64E}\x{1F6A3}\x{1F6B4}-\x{1F6B6}\x{1F926}\x{1F935}\x{1F937}-\x{1F939}\x{1F93C}-\x{1F93E}\x{1F9B8}\x{1F9B9}\x{1F9CD}-\x{1F9CF}\x{1F9D4}\x{1F9D6}-\x{1F9DD}]\x{200D}[\x{2640}\x{2642}]|[\xA9\xAE\x{203C}\x{2049}\x{2122}\x{2139}\x{2194}-\x{2199}\x{21A9}\x{21AA}\x{231A}\x{231B}\x{2328}\x{23CF}\x{23ED}-\x{23EF}\x{23F1}\x{23F2}\x{23F8}-\x{23FA}\x{24C2}\x{25AA}\x{25AB}\x{25B6}\x{25C0}\x{25FB}\x{25FC}\x{25FE}\x{2600}-\x{2604}\x{260E}\x{2611}\x{2614}\x{2615}\x{2618}\x{2620}\x{2622}\x{2623}\x{2626}\x{262A}\x{262E}\x{262F}\x{2638}-\x{263A}\x{2640}\x{2642}\x{2648}-\x{2653}\x{265F}\x{2660}\x{2663}\x{2665}\x{2666}\x{2668}\x{267B}\x{267E}\x{267F}\x{2692}\x{2694}-\x{2697}\x{2699}\x{269B}\x{269C}\x{26A0}\x{26A7}\x{26AA}\x{26B0}\x{26B1}\x{26BD}\x{26BE}\x{26C4}\x{26C8}\x{26CF}\x{26D1}\x{26D3}\x{26E9}\x{26F0}-\x{26F5}\x{26F7}\x{26F8}\x{26FA}\x{2702}\x{2708}\x{2709}\x{270F}\x{2712}\x{2714}\x{2716}\x{271D}\x{2721}\x{2733}\x{2734}\x{2744}\x{2747}\x{2757}\x{2763}\x{27A1}\x{2934}\x{2935}\x{2B05}-\x{2B07}\x{2B1B}\x{2B1C}\x{2B55}\x{3030}\x{303D}\x{3297}\x{3299}\x{1F004}\x{1F170}\x{1F171}\x{1F17E}\x{1F17F}\x{1F202}\x{1F237}\x{1F321}\x{1F324}-\x{1F32C}\x{1F336}\x{1F37D}\x{1F396}\x{1F397}\x{1F399}-\x{1F39B}\x{1F39E}\x{1F39F}\x{1F3CD}\x{1F3CE}\x{1F3D4}-\x{1F3DF}\x{1F3F5}\x{1F3F7}\x{1F43F}\x{1F4FD}\x{1F549}\x{1F54A}\x{1F56F}\x{1F570}\x{1F573}\x{1F576}-\x{1F579}\x{1F587}\x{1F58A}-\x{1F58D}\x{1F5A5}\x{1F5A8}\x{1F5B1}\x{1F5B2}\x{1F5BC}\x{1F5C2}-\x{1F5C4}\x{1F5D1}-\x{1F5D3}\x{1F5DC}-\x{1F5DE}\x{1F5E1}\x{1F5E3}\x{1F5E8}\x{1F5EF}\x{1F5F3}\x{1F5FA}\x{1F6CB}\x{1F6CD}-\x{1F6CF}\x{1F6E0}-\x{1F6E5}\x{1F6E9}\x{1F6F0}\x{1F6F3}])\x{FE0F}|\x{1F441}\x{FE0F}?\x{200D}\x{1F5E8}|\x{1F9D1}(?:\x{1F3FF}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FE}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FD}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FC}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FB}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{200D}[\x{2695}\x{2696}\x{2708}])|\x{1F469}(?:\x{1F3FF}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FE}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FD}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FC}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{1F3FB}\x{200D}[\x{2695}\x{2696}\x{2708}]|\x{200D}[\x{2695}\x{2696}\x{2708}])|\x{1F3F3}\x{FE0F}?\x{200D}\x{1F308}|\x{1F469}\x{200D}\x{1F467}|\x{1F469}\x{200D}\x{1F466}|\x{1F636}\x{200D}\x{1F32B}|\x{1F3F3}\x{FE0F}?\x{200D}\x{26A7}|\x{1F635}\x{200D}\x{1F4AB}|\x{1F62E}\x{200D}\x{1F4A8}|\x{1F415}\x{200D}\x{1F9BA}|\x{1FAF1}(?:\x{1F3FF}|\x{1F3FE}|\x{1F3FD}|\x{1F3FC}|\x{1F3FB})?|\x{1F9D1}(?:\x{1F3FF}|\x{1F3FE}|\x{1F3FD}|\x{1F3FC}|\x{1F3FB})?|\x{1F469}(?:\x{1F3FF}|\x{1F3FE}|\x{1F3FD}|\x{1F3FC}|\x{1F3FB})?|\x{1F43B}\x{200D}\x{2744}|(?:[\x{1F3C3}\x{1F3C4}\x{1F3CA}\x{1F46E}\x{1F470}\x{1F471}\x{1F473}\x{1F477}\x{1F481}\x{1F482}\x{1F486}\x{1F487}\x{1F645}-\x{1F647}\x{1F64B}\x{1F64D}\x{1F64E}\x{1F6A3}\x{1F6B4}-\x{1F6B6}\x{1F926}\x{1F935}\x{1F937}-\x{1F939}\x{1F93D}\x{1F93E}\x{1F9B8}\x{1F9B9}\x{1F9CD}-\x{1F9CF}\x{1F9D4}\x{1F9D6}-\x{1F9DD}][\x{1F3FB}-\x{1F3FF}]|[\x{1F46F}\x{1F9DE}\x{1F9DF}])\x{200D}[\x{2640}\x{2642}]|[\x{26F9}\x{1F3CB}\x{1F3CC}\x{1F575}](?:[\x{FE0F}\x{1F3FB}-\x{1F3FF}]\x{200D}[\x{2640}\x{2642}]|\x{200D}[\x{2640}\x{2642}])|\x{1F3F4}\x{200D}\x{2620}|\x{1F1FD}\x{1F1F0}|\x{1F1F6}\x{1F1E6}|\x{1F1F4}\x{1F1F2}|\x{1F408}\x{200D}\x{2B1B}|\x{2764}(?:\x{FE0F}\x{200D}[\x{1F525}\x{1FA79}]|\x{200D}[\x{1F525}\x{1FA79}])|\x{1F441}\x{FE0F}?|\x{1F3F3}\x{FE0F}?|[\x{1F3C3}\x{1F3C4}\x{1F3CA}\x{1F46E}\x{1F470}\x{1F471}\x{1F473}\x{1F477}\x{1F481}\x{1F482}\x{1F486}\x{1F487}\x{1F645}-\x{1F647}\x{1F64B}\x{1F64D}\x{1F64E}\x{1F6A3}\x{1F6B4}-\x{1F6B6}\x{1F926}\x{1F935}\x{1F937}-\x{1F939}\x{1F93C}-\x{1F93E}\x{1F9B8}\x{1F9B9}\x{1F9CD}-\x{1F9CF}\x{1F9D4}\x{1F9D6}-\x{1F9DD}]\x{200D}[\x{2640}\x{2642}]|\x{1F1FF}[\x{1F1E6}\x{1F1F2}\x{1F1FC}]|\x{1F1FE}[\x{1F1EA}\x{1F1F9}]|\x{1F1FC}[\x{1F1EB}\x{1F1F8}]|\x{1F1FB}[\x{1F1E6}\x{1F1E8}\x{1F1EA}\x{1F1EC}\x{1F1EE}\x{1F1F3}\x{1F1FA}]|\x{1F1FA}[\x{1F1E6}\x{1F1EC}\x{1F1F2}\x{1F1F3}\x{1F1F8}\x{1F1FE}\x{1F1FF}]|\x{1F1F9}[\x{1F1E6}\x{1F1E8}\x{1F1E9}\x{1F1EB}-\x{1F1ED}\x{1F1EF}-\x{1F1F4}\x{1F1F7}\x{1F1F9}\x{1F1FB}\x{1F1FC}\x{1F1FF}]|\x{1F1F8}[\x{1F1E6}-\x{1F1EA}\x{1F1EC}-\x{1F1F4}\x{1F1F7}-\x{1F1F9}\x{1F1FB}\x{1F1FD}-\x{1F1FF}]|\x{1F1F7}[\x{1F1EA}\x{1F1F4}\x{1F1F8}\x{1F1FA}\x{1F1FC}]|\x{1F1F5}[\x{1F1E6}\x{1F1EA}-\x{1F1ED}\x{1F1F0}-\x{1F1F3}\x{1F1F7}-\x{1F1F9}\x{1F1FC}\x{1F1FE}]|\x{1F1F3}[\x{1F1E6}\x{1F1E8}\x{1F1EA}-\x{1F1EC}\x{1F1EE}\x{1F1F1}\x{1F1F4}\x{1F1F5}\x{1F1F7}\x{1F1FA}\x{1F1FF}]|\x{1F1F2}[\x{1F1E6}\x{1F1E8}-\x{1F1ED}\x{1F1F0}-\x{1F1FF}]|\x{1F1F1}[\x{1F1E6}-\x{1F1E8}\x{1F1EE}\x{1F1F0}\x{1F1F7}-\x{1F1FB}\x{1F1FE}]|\x{1F1F0}[\x{1F1EA}\x{1F1EC}-\x{1F1EE}\x{1F1F2}\x{1F1F3}\x{1F1F5}\x{1F1F7}\x{1F1FC}\x{1F1FE}\x{1F1FF}]|\x{1F1EF}[\x{1F1EA}\x{1F1F2}\x{1F1F4}\x{1F1F5}]|\x{1F1EE}[\x{1F1E8}-\x{1F1EA}\x{1F1F1}-\x{1F1F4}\x{1F1F6}-\x{1F1F9}]|\x{1F1ED}[\x{1F1F0}\x{1F1F2}\x{1F1F3}\x{1F1F7}\x{1F1F9}\x{1F1FA}]|\x{1F1EC}[\x{1F1E6}\x{1F1E7}\x{1F1E9}-\x{1F1EE}\x{1F1F1}-\x{1F1F3}\x{1F1F5}-\x{1F1FA}\x{1F1FC}\x{1F1FE}]|\x{1F1EB}[\x{1F1EE}-\x{1F1F0}\x{1F1F2}\x{1F1F4}\x{1F1F7}]|\x{1F1EA}[\x{1F1E6}\x{1F1E8}\x{1F1EA}\x{1F1EC}\x{1F1ED}\x{1F1F7}-\x{1F1FA}]|\x{1F1E9}[\x{1F1EA}\x{1F1EC}\x{1F1EF}\x{1F1F0}\x{1F1F2}\x{1F1F4}\x{1F1FF}]|\x{1F1E8}[\x{1F1E6}\x{1F1E8}\x{1F1E9}\x{1F1EB}-\x{1F1EE}\x{1F1F0}-\x{1F1F5}\x{1F1F7}\x{1F1FA}-\x{1F1FF}]|\x{1F1E7}[\x{1F1E6}\x{1F1E7}\x{1F1E9}-\x{1F1EF}\x{1F1F1}-\x{1F1F4}\x{1F1F6}-\x{1F1F9}\x{1F1FB}\x{1F1FC}\x{1F1FE}\x{1F1FF}]|\x{1F1E6}[\x{1F1E8}-\x{1F1EC}\x{1F1EE}\x{1F1F1}\x{1F1F2}\x{1F1F4}\x{1F1F6}-\x{1F1FA}\x{1F1FC}\x{1F1FD}\x{1F1FF}]|[#\*0-9]\x{FE0F}?\x{20E3}|\x{1F93C}[\x{1F3FB}-\x{1F3FF}]|\x{2764}\x{FE0F}?|[\x{1F3C3}\x{1F3C4}\x{1F3CA}\x{1F46E}\x{1F470}\x{1F471}\x{1F473}\x{1F477}\x{1F481}\x{1F482}\x{1F486}\x{1F487}\x{1F645}-\x{1F647}\x{1F64B}\x{1F64D}\x{1F64E}\x{1F6A3}\x{1F6B4}-\x{1F6B6}\x{1F926}\x{1F935}\x{1F937}-\x{1F939}\x{1F93D}\x{1F93E}\x{1F9B8}\x{1F9B9}\x{1F9CD}-\x{1F9CF}\x{1F9D4}\x{1F9D6}-\x{1F9DD}][\x{1F3FB}-\x{1F3FF}]|[\x{26F9}\x{1F3CB}\x{1F3CC}\x{1F575}][\x{FE0F}\x{1F3FB}-\x{1F3FF}]?|\x{1F3F4}|[\x{270A}\x{270B}\x{1F385}\x{1F3C2}\x{1F3C7}\x{1F442}\x{1F443}\x{1F446}-\x{1F450}\x{1F466}\x{1F467}\x{1F46B}-\x{1F46D}\x{1F472}\x{1F474}-\x{1F476}\x{1F478}\x{1F47C}\x{1F483}\x{1F485}\x{1F48F}\x{1F491}\x{1F4AA}\x{1F57A}\x{1F595}\x{1F596}\x{1F64C}\x{1F64F}\x{1F6C0}\x{1F6CC}\x{1F90C}\x{1F90F}\x{1F918}-\x{1F91F}\x{1F930}-\x{1F934}\x{1F936}\x{1F977}\x{1F9B5}\x{1F9B6}\x{1F9BB}\x{1F9D2}\x{1F9D3}\x{1F9D5}\x{1FAC3}-\x{1FAC5}\x{1FAF0}\x{1FAF2}-\x{1FAF6}][\x{1F3FB}-\x{1F3FF}]|[\x{261D}\x{270C}\x{270D}\x{1F574}\x{1F590}][\x{FE0F}\x{1F3FB}-\x{1F3FF}]|[\x{261D}\x{270A}-\x{270D}\x{1F385}\x{1F3C2}\x{1F3C7}\x{1F408}\x{1F415}\x{1F43B}\x{1F442}\x{1F443}\x{1F446}-\x{1F450}\x{1F466}\x{1F467}\x{1F46B}-\x{1F46D}\x{1F472}\x{1F474}-\x{1F476}\x{1F478}\x{1F47C}\x{1F483}\x{1F485}\x{1F48F}\x{1F491}\x{1F4AA}\x{1F574}\x{1F57A}\x{1F590}\x{1F595}\x{1F596}\x{1F62E}\x{1F635}\x{1F636}\x{1F64C}\x{1F64F}\x{1F6C0}\x{1F6CC}\x{1F90C}\x{1F90F}\x{1F918}-\x{1F91F}\x{1F930}-\x{1F934}\x{1F936}\x{1F93C}\x{1F977}\x{1F9B5}\x{1F9B6}\x{1F9BB}\x{1F9D2}\x{1F9D3}\x{1F9D5}\x{1FAC3}-\x{1FAC5}\x{1FAF0}\x{1FAF2}-\x{1FAF6}]|[\x{1F3C3}\x{1F3C4}\x{1F3CA}\x{1F46E}\x{1F470}\x{1F471}\x{1F473}\x{1F477}\x{1F481}\x{1F482}\x{1F486}\x{1F487}\x{1F645}-\x{1F647}\x{1F64B}\x{1F64D}\x{1F64E}\x{1F6A3}\x{1F6B4}-\x{1F6B6}\x{1F926}\x{1F935}\x{1F937}-\x{1F939}\x{1F93D}\x{1F93E}\x{1F9B8}\x{1F9B9}\x{1F9CD}-\x{1F9CF}\x{1F9D4}\x{1F9D6}-\x{1F9DD}]|[\x{1F46F}\x{1F9DE}\x{1F9DF}]|[\xA9\xAE\x{203C}\x{2049}\x{2122}\x{2139}\x{2194}-\x{2199}\x{21A9}\x{21AA}\x{231A}\x{231B}\x{2328}\x{23CF}\x{23ED}-\x{23EF}\x{23F1}\x{23F2}\x{23F8}-\x{23FA}\x{24C2}\x{25AA}\x{25AB}\x{25B6}\x{25C0}\x{25FB}\x{25FC}\x{25FE}\x{2600}-\x{2604}\x{260E}\x{2611}\x{2614}\x{2615}\x{2618}\x{2620}\x{2622}\x{2623}\x{2626}\x{262A}\x{262E}\x{262F}\x{2638}-\x{263A}\x{2640}\x{2642}\x{2648}-\x{2653}\x{265F}\x{2660}\x{2663}\x{2665}\x{2666}\x{2668}\x{267B}\x{267E}\x{267F}\x{2692}\x{2694}-\x{2697}\x{2699}\x{269B}\x{269C}\x{26A0}\x{26A7}\x{26AA}\x{26B0}\x{26B1}\x{26BD}\x{26BE}\x{26C4}\x{26C8}\x{26CF}\x{26D1}\x{26D3}\x{26E9}\x{26F0}-\x{26F5}\x{26F7}\x{26F8}\x{26FA}\x{2702}\x{2708}\x{2709}\x{270F}\x{2712}\x{2714}\x{2716}\x{271D}\x{2721}\x{2733}\x{2734}\x{2744}\x{2747}\x{2757}\x{2763}\x{27A1}\x{2934}\x{2935}\x{2B05}-\x{2B07}\x{2B1B}\x{2B1C}\x{2B55}\x{3030}\x{303D}\x{3297}\x{3299}\x{1F004}\x{1F170}\x{1F171}\x{1F17E}\x{1F17F}\x{1F202}\x{1F237}\x{1F321}\x{1F324}-\x{1F32C}\x{1F336}\x{1F37D}\x{1F396}\x{1F397}\x{1F399}-\x{1F39B}\x{1F39E}\x{1F39F}\x{1F3CD}\x{1F3CE}\x{1F3D4}-\x{1F3DF}\x{1F3F5}\x{1F3F7}\x{1F43F}\x{1F4FD}\x{1F549}\x{1F54A}\x{1F56F}\x{1F570}\x{1F573}\x{1F576}-\x{1F579}\x{1F587}\x{1F58A}-\x{1F58D}\x{1F5A5}\x{1F5A8}\x{1F5B1}\x{1F5B2}\x{1F5BC}\x{1F5C2}-\x{1F5C4}\x{1F5D1}-\x{1F5D3}\x{1F5DC}-\x{1F5DE}\x{1F5E1}\x{1F5E3}\x{1F5E8}\x{1F5EF}\x{1F5F3}\x{1F5FA}\x{1F6CB}\x{1F6CD}-\x{1F6CF}\x{1F6E0}-\x{1F6E5}\x{1F6E9}\x{1F6F0}\x{1F6F3}]|[\x{23E9}-\x{23EC}\x{23F0}\x{23F3}\x{25FD}\x{2693}\x{26A1}\x{26AB}\x{26C5}\x{26CE}\x{26D4}\x{26EA}\x{26FD}\x{2705}\x{2728}\x{274C}\x{274E}\x{2753}-\x{2755}\x{2795}-\x{2797}\x{27B0}\x{27BF}\x{2B50}\x{1F0CF}\x{1F18E}\x{1F191}-\x{1F19A}\x{1F201}\x{1F21A}\x{1F22F}\x{1F232}-\x{1F236}\x{1F238}-\x{1F23A}\x{1F250}\x{1F251}\x{1F300}-\x{1F320}\x{1F32D}-\x{1F335}\x{1F337}-\x{1F37C}\x{1F37E}-\x{1F384}\x{1F386}-\x{1F393}\x{1F3A0}-\x{1F3C1}\x{1F3C5}\x{1F3C6}\x{1F3C8}\x{1F3C9}\x{1F3CF}-\x{1F3D3}\x{1F3E0}-\x{1F3F0}\x{1F3F8}-\x{1F407}\x{1F409}-\x{1F414}\x{1F416}-\x{1F43A}\x{1F43C}-\x{1F43E}\x{1F440}\x{1F444}\x{1F445}\x{1F451}-\x{1F465}\x{1F46A}\x{1F479}-\x{1F47B}\x{1F47D}-\x{1F480}\x{1F484}\x{1F488}-\x{1F48E}\x{1F490}\x{1F492}-\x{1F4A9}\x{1F4AB}-\x{1F4FC}\x{1F4FF}-\x{1F53D}\x{1F54B}-\x{1F54E}\x{1F550}-\x{1F567}\x{1F5A4}\x{1F5FB}-\x{1F62D}\x{1F62F}-\x{1F634}\x{1F637}-\x{1F644}\x{1F648}-\x{1F64A}\x{1F680}-\x{1F6A2}\x{1F6A4}-\x{1F6B3}\x{1F6B7}-\x{1F6BF}\x{1F6C1}-\x{1F6C5}\x{1F6D0}-\x{1F6D2}\x{1F6D5}-\x{1F6D7}\x{1F6DD}-\x{1F6DF}\x{1F6EB}\x{1F6EC}\x{1F6F4}-\x{1F6FC}\x{1F7E0}-\x{1F7EB}\x{1F7F0}\x{1F90D}\x{1F90E}\x{1F910}-\x{1F917}\x{1F920}-\x{1F925}\x{1F927}-\x{1F92F}\x{1F93A}\x{1F93F}-\x{1F945}\x{1F947}-\x{1F976}\x{1F978}-\x{1F9B4}\x{1F9B7}\x{1F9BA}\x{1F9BC}-\x{1F9CC}\x{1F9D0}\x{1F9E0}-\x{1F9FF}\x{1FA70}-\x{1FA74}\x{1FA78}-\x{1FA7C}\x{1FA80}-\x{1FA86}\x{1FA90}-\x{1FAAC}\x{1FAB0}-\x{1FABA}\x{1FAC0}-\x{1FAC2}\x{1FAD0}-\x{1FAD9}\x{1FAE0}-\x{1FAE7}]"""
-}
\ No newline at end of file
diff --git a/mirai-core/src/nativeMain/kotlin/network/component/getComponentTypeArgument.kt b/mirai-core/src/nativeMain/kotlin/network/component/getComponentTypeArgument.kt
deleted file mode 100644
index 82435478a..000000000
--- a/mirai-core/src/nativeMain/kotlin/network/component/getComponentTypeArgument.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.network.component
-
-import kotlin.reflect.KTypeProjection
-
-internal actual fun ComponentKey<*>.getComponentTypeArgument(): KTypeProjection? = null
\ No newline at end of file
diff --git a/mirai-core/src/nativeMain/kotlin/network/handler/LengthDelimitedPacketReader.kt b/mirai-core/src/nativeMain/kotlin/network/handler/LengthDelimitedPacketReader.kt
deleted file mode 100644
index cc7c854c3..000000000
--- a/mirai-core/src/nativeMain/kotlin/network/handler/LengthDelimitedPacketReader.kt
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.network.handler
-
-import io.ktor.utils.io.core.*
-import net.mamoe.mirai.utils.*
-import net.mamoe.mirai.utils.Closeable
-
-private val debugLogger: MiraiLogger by lazy {
- MiraiLogger.Factory.create(
- LengthDelimitedPacketReader::class, "LengthDelimitedPacketReader"
- ).withSwitch(systemProp("mirai.network.handler.length.delimited.packet.reader.debug", false))
-}
-
-/**
- * Not thread-safe
- */
-internal class LengthDelimitedPacketReader(
- private val sendDecode: (combined: ByteReadPacket) -> Unit
-) : Closeable {
- private var missingLength: Long = 0
- set(value) {
- field = value
- debugLogger.info { "missingLength = $field" }
- }
- private val bufferedParts: MutableList = ArrayList(10)
-
- @TestOnly
- fun getMissingLength() = missingLength
-
- @TestOnly
- fun getBufferedPackets() = bufferedParts.toList()
-
- fun offer(packet: ByteReadPacket) {
- if (missingLength == 0L) {
- // initial
- debugLogger.info { "initial length == 0" }
- missingLength = packet.readInt().toLongUnsigned() - 4
- }
- debugLogger.info { "Offering packet len = ${packet.remaining}" }
- missingLength -= packet.remaining
- bufferedParts.add(packet)
- if (missingLength <= 0) {
- emit()
- }
- }
-
- private fun emit() {
- debugLogger.info { "Emitting, buffered = ${bufferedParts.map { it.remaining }}" }
- when (bufferedParts.size) {
- 0 -> {}
- 1 -> {
- val part = bufferedParts.first()
- if (missingLength == 0L) {
- debugLogger.info { "Single packet length perfectly matched." }
- sendDecode(part)
-
- bufferedParts.clear()
- } else {
- check(missingLength < 0L) { "Failed check: remainingLength < 0L" }
-
- val previousPacketLength = missingLength + part.remaining
- debugLogger.info { "Got extra packets, previousPacketLength = $previousPacketLength" }
- sendDecode(part.readPacketExact(previousPacketLength.toInt()))
-
- bufferedParts.clear()
-
- // now packet contain new part.
- missingLength = part.readInt().toLongUnsigned() - 4
- offer(part)
- }
- }
- else -> {
- if (missingLength == 0L) {
- debugLogger.info { "Multiple packets length perfectly matched." }
- sendDecode(buildPacket {
- bufferedParts.forEach { writePacket(it) }
- })
-
- bufferedParts.clear()
- } else {
- val lastPart = bufferedParts.last()
- val previousPacketPartLength = missingLength + lastPart.remaining
- debugLogger.debug { "previousPacketPartLength = $previousPacketPartLength" }
- val combinedLength =
- (bufferedParts.sumOf { it.remaining } - lastPart.remaining // buffered length without last part
- + previousPacketPartLength).toInt()
- debugLogger.debug { "combinedLength = $combinedLength" }
-
- if (combinedLength < 0) return // not enough, still more parts missing.
-
- sendDecode(buildPacket {
- repeat(bufferedParts.size - 1) { i ->
- writePacket(bufferedParts[i])
- }
- writePacket(lastPart, previousPacketPartLength)
- })
-
- bufferedParts.clear()
-
- // now packet contain new part.
- missingLength = lastPart.readInt().toLongUnsigned() - 4
- offer(lastPart)
- }
-
- }
- }
- }
-
- override fun close() {
- bufferedParts.forEach { it.close() }
- }
-}
diff --git a/mirai-core/src/nativeMain/kotlin/network/handler/NativeNetworkHandler.kt b/mirai-core/src/nativeMain/kotlin/network/handler/NativeNetworkHandler.kt
deleted file mode 100644
index 599d40711..000000000
--- a/mirai-core/src/nativeMain/kotlin/network/handler/NativeNetworkHandler.kt
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.network.handler
-
-import io.ktor.utils.io.*
-import io.ktor.utils.io.core.*
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.cancel
-import kotlinx.coroutines.channels.Channel
-import kotlinx.coroutines.channels.onFailure
-import kotlinx.coroutines.isActive
-import kotlinx.coroutines.launch
-import net.mamoe.mirai.internal.network.components.PacketCodec
-import net.mamoe.mirai.internal.network.components.SsoProcessor
-import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket
-import net.mamoe.mirai.internal.utils.PlatformSocket
-import net.mamoe.mirai.internal.utils.connect
-import net.mamoe.mirai.utils.childScope
-import net.mamoe.mirai.utils.info
-
-internal class NativeNetworkHandler(
- context: NetworkHandlerContext,
- address: SocketAddress
-) : CommonNetworkHandler(context, address) {
- internal object Factory : NetworkHandlerFactory {
- override fun create(context: NetworkHandlerContext, address: SocketAddress): NativeNetworkHandler {
- return NativeNetworkHandler(context, address)
- }
- }
-
- internal inner class NativeConn(
- private val socket: PlatformSocket,
- ) : Closeable, CoroutineScope by coroutineContext.childScope("NativeConn") {
- private val decodePipeline: PacketDecodePipeline = PacketDecodePipeline(this.coroutineContext)
-
- private val packetCodec: PacketCodec by lazy { context[PacketCodec] }
- private val ssoProcessor: SsoProcessor by lazy { context[SsoProcessor] }
-
- private val sendQueue: Channel = Channel(Channel.BUFFERED) { undelivered ->
- launch { write(undelivered) }
- }
-
- private val lengthDelimitedPacketReader = LengthDelimitedPacketReader(decodePipeline::send)
-
- init {
- launch {
- while (isActive) {
- val result = sendQueue.receiveCatching()
- logger.info { "Native sender: $result" }
- result.onFailure { if (it is CancellationException) return@launch }
-
- result.getOrNull()?.let { packet ->
- try {
- socket.send(packet.delegate, 0, packet.delegate.size)
- } catch (e: Throwable) {
- if (e is CancellationException) return@launch
- logger.error("Error while sending packet '${packet.commandName}'", e)
- }
- }
- }
- }
-
- launch {
- while (isActive) {
- try {
- val packet = socket.read()
-
- lengthDelimitedPacketReader.offer(packet)
- } catch (e: Throwable) {
- if (e is CancellationException) return@launch
- logger.error("Error while reading packet.", e)
- setState { StateClosed(e) }
- }
- }
- }
- }
-
- fun write(packet: OutgoingPacket) {
- sendQueue.trySend(packet).onFailure {
- throw it
- ?: throw IllegalStateException("Internal error: Failed to send packet '${packet.commandName}' without reason.")
- }
- }
-
- override fun close() {
- cancel()
- sendQueue.close()
- }
- }
-
- override suspend fun createConnection(): NativeConn {
- logger.info { "Connecting to $address" }
- return NativeConn(PlatformSocket.connect(address)).also {
- logger.info { "Connected to server $address" }
- }
- }
-
- @Suppress("EXTENSION_SHADOWED_BY_MEMBER")
- override fun NativeConn.close() {
- this.close()
- }
-
- override fun NativeConn.writeAndFlushOrCloseAsync(packet: OutgoingPacket) {
- write(packet)
- }
-}
\ No newline at end of file
diff --git a/mirai-core/src/nativeMain/kotlin/network/handler/NetworkHandlerFactory.kt b/mirai-core/src/nativeMain/kotlin/network/handler/NetworkHandlerFactory.kt
deleted file mode 100644
index 4eb675111..000000000
--- a/mirai-core/src/nativeMain/kotlin/network/handler/NetworkHandlerFactory.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.network.handler
-
-/**
- * Factory for a specific [NetworkHandler] implementation.
- */
-internal actual fun interface NetworkHandlerFactory {
- actual fun create(
- context: NetworkHandlerContext,
- host: String,
- port: Int
- ): H = create(context, SocketAddressImpl(host, port))
-
- /**
- * Create an instance of [H]. The returning [H] has [NetworkHandler.state] of [State.INITIALIZED]
- */
- actual fun create(
- context: NetworkHandlerContext,
- address: SocketAddress
- ): H
-
- actual companion object {
- actual fun getPlatformDefault(): NetworkHandlerFactory<*> = NativeNetworkHandler.Factory
- }
-}
\ No newline at end of file
diff --git a/mirai-core/src/nativeMain/kotlin/network/handler/SocketAddress.kt b/mirai-core/src/nativeMain/kotlin/network/handler/SocketAddress.kt
deleted file mode 100644
index 2baca8668..000000000
--- a/mirai-core/src/nativeMain/kotlin/network/handler/SocketAddress.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.network.handler
-
-internal actual abstract class SocketAddress(
- val host: String,
- val port: Int,
- @Suppress("UNUSED_PARAMETER") constructorMarker: Unit?, // avoid ambiguity with function SocketAddress
-)
-
-internal actual fun SocketAddress.getHost(): String = host
-internal actual fun SocketAddress.getPort(): Int = port
-
-
-internal class SocketAddressImpl(host: String, port: Int) : SocketAddress(host, port, null) {
- override fun toString(): String {
- return "$host:$port"
- }
-}
-
-internal actual fun createSocketAddress(host: String, port: Int): SocketAddress {
- return SocketAddressImpl(host, port)
-}
-
diff --git a/mirai-core/src/nativeMain/kotlin/network/handler/selector/SelectorRequireReconnectException.kt b/mirai-core/src/nativeMain/kotlin/network/handler/selector/SelectorRequireReconnectException.kt
deleted file mode 100644
index 040bd49dc..000000000
--- a/mirai-core/src/nativeMain/kotlin/network/handler/selector/SelectorRequireReconnectException.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.network.handler.selector
-
-internal actual class SelectorRequireReconnectException : NetworkException(true)
diff --git a/mirai-core/src/nativeMain/kotlin/network/protocol/data/richstatus/parseRichStatusImpl.kt b/mirai-core/src/nativeMain/kotlin/network/protocol/data/richstatus/parseRichStatusImpl.kt
deleted file mode 100644
index 632bbcc95..000000000
--- a/mirai-core/src/nativeMain/kotlin/network/protocol/data/richstatus/parseRichStatusImpl.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.network.protocol.data.richstatus
-
-internal actual fun parseRichStatusImpl(rawData: ByteArray?): RichStatus {
- return RichStatus()
-}
\ No newline at end of file
diff --git a/mirai-core/src/nativeMain/kotlin/package.kt b/mirai-core/src/nativeMain/kotlin/package.kt
deleted file mode 100644
index 7df5cebc4..000000000
--- a/mirai-core/src/nativeMain/kotlin/package.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal
\ No newline at end of file
diff --git a/mirai-core/src/nativeMain/kotlin/utils/PlatformSocket.kt b/mirai-core/src/nativeMain/kotlin/utils/PlatformSocket.kt
deleted file mode 100644
index e32e0fbb9..000000000
--- a/mirai-core/src/nativeMain/kotlin/utils/PlatformSocket.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.utils
-
-import io.ktor.utils.io.errors.*
-
-internal actual class SocketException : IOException {
- actual constructor() : super("", null)
-
- actual constructor(message: String) : super(message)
-}
-
-internal actual class NoRouteToHostException : IOException {
- actual constructor() : super("")
- actual constructor(message: String) : super(message)
-}
-
-internal actual class UnknownHostException : IOException {
- actual constructor() : super("")
- actual constructor(message: String) : super(message)
-}
diff --git a/mirai-core/src/nativeMain/kotlin/utils/crypto/AESNative.kt b/mirai-core/src/nativeMain/kotlin/utils/crypto/AESNative.kt
deleted file mode 100644
index b9b52d465..000000000
--- a/mirai-core/src/nativeMain/kotlin/utils/crypto/AESNative.kt
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2019-2023 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.utils.crypto
-
-import kotlinx.cinterop.*
-import net.mamoe.mirai.internal.utils.free
-import net.mamoe.mirai.internal.utils.getOpenSSLError
-import openssl.*
-
-private val aes256CBC by lazy { EVP_aes_256_cbc() }
-
-internal actual fun aesEncrypt(input: ByteArray, iv: ByteArray, key: ByteArray): ByteArray {
- return doAES(input, iv, key, true)
-}
-
-internal actual fun aesDecrypt(input: ByteArray, iv: ByteArray, key: ByteArray): ByteArray {
- return doAES(input, iv, key, false)
-}
-
-/**
- * reference:
- * - https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption
- */
-private fun doAES(input: ByteArray, iv: ByteArray, key: ByteArray, doEncrypt: Boolean): ByteArray {
- memScoped {
- val evpCipherCtx = EVP_CIPHER_CTX_new() ?: error("Failed to create evp cipher context: ${getOpenSSLError()}")
-
- val pinnedKey = key.pin()
- val pinnedIv = iv.pin()
- val pinnedInput = input.pin()
-
- if (1 != EVP_CipherInit(
- ctx = evpCipherCtx,
- cipher = aes256CBC,
- key = pinnedKey.addressOf(0).reinterpret(),
- iv = pinnedIv.addressOf(0).reinterpret(),
- enc = if (doEncrypt) 1 else 0
- )
- ) {
- pinnedKey.unpin()
- pinnedIv.unpin()
- pinnedInput.unpin()
- EVP_CIPHER_CTX_free(evpCipherCtx)
- error("Failed to init aes-256-cbc cipher: ${getOpenSSLError()}")
- }
-
- pinnedKey.unpin()
- pinnedIv.unpin()
-
- val blockSize = _evpCipherCtxGetBlockSize(evpCipherCtx)
- val cipherBufferSize = pinnedInput.get().size + blockSize - (pinnedInput.get().size % blockSize)
- val pinnedCipherBuffer = ByteArray(cipherBufferSize.convert()).pin()
-
-
- val tempLen = alloc()
- val cipherSize = alloc()
-
- if (1 != EVP_CipherUpdate(
- ctx = evpCipherCtx,
- out = pinnedCipherBuffer.addressOf(0).reinterpret(),
- outl = tempLen.ptr,
- `in` = pinnedInput.addressOf(0).reinterpret(),
- inl = pinnedInput.get().size.convert()
- )
- ) {
- pinnedInput.unpin()
- pinnedCipherBuffer.unpin()
- free(tempLen.ptr, cipherSize.ptr)
- EVP_CIPHER_CTX_free(evpCipherCtx)
- error("Failed do aes-256-cbc cipher update: ${getOpenSSLError()}")
- }
- cipherSize.value = tempLen.value
-
- if (1 != EVP_CipherFinal(
- ctx = evpCipherCtx,
- outm = pinnedCipherBuffer.addressOf(tempLen.value).reinterpret(),
- outl = tempLen.ptr
- )
- ) {
- pinnedInput.unpin()
- pinnedCipherBuffer.unpin()
- free(tempLen.ptr, cipherSize.ptr)
- EVP_CIPHER_CTX_free(evpCipherCtx)
- error("Failed do aes-256-cbc cipher final: ${getOpenSSLError()}")
- }
- cipherSize.value += tempLen.value
-
- return pinnedCipherBuffer.get().copyOf(cipherSize.value).also {
- pinnedInput.unpin()
- pinnedCipherBuffer.unpin()
- EVP_CIPHER_CTX_free(evpCipherCtx)
- }
- }
-}
diff --git a/mirai-core/src/nativeMain/kotlin/utils/crypto/EcdhNative.kt b/mirai-core/src/nativeMain/kotlin/utils/crypto/EcdhNative.kt
deleted file mode 100644
index 84c6c1bc7..000000000
--- a/mirai-core/src/nativeMain/kotlin/utils/crypto/EcdhNative.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.utils.crypto
-
-
-internal actual fun Ecdh.Companion.create(): Ecdh<*, *> = OpenSslEcdh()
\ No newline at end of file
diff --git a/mirai-core/src/nativeMain/kotlin/utils/crypto/OpenSslEcdh.kt b/mirai-core/src/nativeMain/kotlin/utils/crypto/OpenSslEcdh.kt
deleted file mode 100644
index 9802129f8..000000000
--- a/mirai-core/src/nativeMain/kotlin/utils/crypto/OpenSslEcdh.kt
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
- *
- * https://github.com/mamoe/mirai/blob/dev/LICENSE
- */
-
-package net.mamoe.mirai.internal.utils.crypto
-
-import kotlinx.cinterop.*
-import openssl.*
-import platform.posix.errno
-import kotlin.native.internal.createCleaner
-
-private const val curveId = NID_X9_62_prime256v1
-private val group by lazy { EC_GROUP_new_by_curve_name(curveId) ?: error("Failed to get EC_GROUP") }
-private val convForm by lazy { EC_GROUP_get_point_conversion_form(group) }
-private val bnCtx by lazy { BN_CTX_new() }
-
-
-internal class OpenSslECPublicKey private constructor(val point: CPointer) {
- @Suppress("unused")
- @OptIn(ExperimentalStdlibApi::class)
- private val cleaner = createCleaner(point) {
- EC_POINT_free(it)
- }
-
- fun export(): ByteArray {
- val len = EC_POINT_point2oct(group, point, convForm, null, 0, null)
- val bytes = ByteArray(len.convert())
- bytes.usePinned {
- EC_POINT_point2oct(group, point, convForm, it.addressOf(0).reinterpret(), len, bnCtx)
- }
- return bytes
- }
-
- override fun equals(other: Any?): Boolean {
- if (this === other) return true
- return (other as? OpenSslECPublicKey)?.let {
- EC_POINT_cmp(group, point, it.point, bnCtx) == 0
- } ?: false
- }
-
- override fun hashCode(): Int {
- return export().hashCode()
- }
-
- companion object {
- fun copyFrom(source: CPointer): OpenSslECPublicKey {
- return OpenSslECPublicKey(EC_POINT_dup(source, group) ?: error("Failed to dup a EC_POINT"))
- }
-
- fun import(encoded: ByteArray): OpenSslECPublicKey {
- val point = EC_POINT_new(group) ?: error("Failed to create EC_POINT")
- encoded.usePinned {
- EC_POINT_oct2point(group, point, it.addressOf(0).reinterpret(), it.get().size.convert(), bnCtx)
- }
- return OpenSslECPublicKey(point)
- }
- }
-}
-
-internal class OpenSslECPrivateKey private constructor(val bn: CPointer) {
- @Suppress("unused")
- @OptIn(ExperimentalStdlibApi::class)
- private val cleaner = createCleaner(bn) {
- BN_free(it)
- }
-
- override fun equals(other: Any?): Boolean {
- if (this === other) return true
- return (other as? OpenSslECPrivateKey)?.let {
- BN_cmp(bn, other.bn) == 0
- } ?: false
- }
-
- fun export(): ByteArray {
- val len = (BN_num_bits(bn)+7)/8
- val bytes = ByteArray(len)
- bytes.usePinned {
- BN_bn2bin(bn, it.addressOf(0).reinterpret())
- }
- return bytes
- }
-
- override fun hashCode(): Int {
- return export().hashCode()
- }
-
- companion object {
- fun copyFrom(source: CPointer