diff --git a/.github/workflows/network-pressure.yml b/.github/workflows/network-pressure.yml
deleted file mode 100644
index def9761df..000000000
--- a/.github/workflows/network-pressure.yml
+++ /dev/null
@@ -1,61 +0,0 @@
-name: Network Pressure Test
-
-on:
- pull_request:
- branches:
- - main
-
-jobs:
- network-pressure-10-clients-ubuntu-rel:
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v2
-
- - name: Setup .NET Core
- uses: actions/setup-dotnet@v1
- with:
- dotnet-version: '6.0.x'
-
- - name: Restore NuGet packages
- run: |
- dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
- dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
-
- - name: Run tests
- run: cd Tests/KcpTests/KcpPerformanceTest ; dotnet run --configuration Release -- --packet-size 3500 --packet-repeat-time 5000 --packet-interval 50 --github-actions --clients-count 10
-
- - name: Archive logs
- uses: actions/upload-artifact@v2
- with:
- name: Report & logs (ubuntu-rel-pressure-x10) - ${{ github.sha }}
- path: Tests/KcpTests/KcpPerformanceTest/logs
- retention-days: 21
-
- network-pressure-20-clients-ubuntu-rel:
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v2
-
- - name: Setup .NET Core
- uses: actions/setup-dotnet@v1
- with:
- dotnet-version: '6.0.x'
-
- - name: Restore NuGet packages
- run: |
- dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
- dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
-
- - name: Run tests
- run: cd Tests/KcpTests/KcpPerformanceTest ; dotnet run --configuration Release -- --packet-size 3500 --packet-repeat-time 5000 --packet-interval 50 --github-actions --clients-count 20
-
- - name: Archive logs
- uses: actions/upload-artifact@v2
- with:
- name: Report & logs (ubuntu-rel-pressure-x20) - ${{ github.sha }}
- path: Tests/KcpTests/KcpPerformanceTest/logs
- retention-days: 21
\ No newline at end of file
diff --git a/.github/workflows/network-test.yml b/.github/workflows/network-test.yml
deleted file mode 100644
index c1c6fbde9..000000000
--- a/.github/workflows/network-test.yml
+++ /dev/null
@@ -1,118 +0,0 @@
-# Generated By ChatGPT
-name: Network Test
-
-on:
- pull_request:
- branches:
- - main
-
-jobs:
- network-proxy-benchmark-windows-rel:
- runs-on: windows-latest
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v2
-
- - name: Setup .NET Core
- uses: actions/setup-dotnet@v1
- with:
- dotnet-version: '6.0.x'
-
- - name: Restore NuGet packages
- run: |
- dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
- dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
-
- - name: Run tests
- run: cd Tests/KcpTests/KcpPerformanceTest ; dotnet run --configuration Release -- --packet-size 3500 --packet-repeat-time 5000 --packet-interval 40 --github-actions --clients-count 2 --packet-delay-log
-
- - name: Archive logs
- uses: actions/upload-artifact@v2
- with:
- name: Report & logs (proxy-windows-rel) - ${{ github.sha }}
- path: Tests/KcpTests/KcpPerformanceTest/logs
- retention-days: 21
-
- network-proxy-benchmark-ubuntu-rel:
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v2
-
- - name: Setup .NET Core
- uses: actions/setup-dotnet@v1
- with:
- dotnet-version: '6.0.x'
-
- - name: Restore NuGet packages
- run: |
- dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
- dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
-
- - name: Run tests
- run: cd Tests/KcpTests/KcpPerformanceTest ; dotnet run --configuration Release -- --packet-size 3500 --packet-repeat-time 5000 --packet-interval 40 --github-actions --clients-count 2 --packet-delay-log
-
- - name: Archive logs
- uses: actions/upload-artifact@v2
- with:
- name: Report & logs (proxy-ubuntu-rel) - ${{ github.sha }}
- path: Tests/KcpTests/KcpPerformanceTest/logs
- retention-days: 21
-
- network-directly-connect-benchmark-windows-rel:
- runs-on: windows-latest
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v2
-
- - name: Setup .NET Core
- uses: actions/setup-dotnet@v1
- with:
- dotnet-version: '6.0.x'
-
- - name: Restore NuGet packages
- run: |
- dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
- dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
-
- - name: Run tests
- # Generated by ChatGPT
- run: cd Tests/KcpTests/KcpPerformanceTest ; dotnet run --configuration Release --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bCONNECT_SERVERONLY -- --packet-size 3500 --packet-repeat-time 5000 --packet-interval 40 --github-actions --clients-count 2 --packet-delay-log
-
- - name: Archive logs
- uses: actions/upload-artifact@v2
- with:
- name: Report & logs (directly-windows-rel) - ${{ github.sha }}
- path: Tests/KcpTests/KcpPerformanceTest/logs
- retention-days: 21
-
- network-directly-connect-benchmark-ubuntu-rel:
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v2
-
- - name: Setup .NET Core
- uses: actions/setup-dotnet@v1
- with:
- dotnet-version: '6.0.x'
-
- - name: Restore NuGet packages
- run: |
- dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
- dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
-
- - name: Run tests
- # Generated by ChatGPT
- run: cd Tests/KcpTests/KcpPerformanceTest ; dotnet run --configuration Release --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bCONNECT_SERVERONLY -- --packet-size 3500 --packet-repeat-time 5000 --packet-interval 40 --github-actions --clients-count 2 --packet-delay-log
-
- - name: Archive logs
- uses: actions/upload-artifact@v2
- with:
- name: Report & logs (directly-ubuntu-rel) - ${{ github.sha }}
- path: Tests/KcpTests/KcpPerformanceTest/logs
- retention-days: 21
diff --git a/.github/workflows/network-tests.yml b/.github/workflows/network-tests.yml
new file mode 100644
index 000000000..352c46c02
--- /dev/null
+++ b/.github/workflows/network-tests.yml
@@ -0,0 +1,1315 @@
+# Generated By ChatGPT
+name: Network Test
+
+on:
+ pull_request:
+ branches:
+ - main
+ - development
+ push:
+ branches:
+ - main
+ - development
+ - byte-check-mode
+
+jobs:
+
+ # Quick Check
+
+ net-debug-direct-ubuntu:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Debug
+ --property:DefineConstants=TRACE%3bDEBUG%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bCONNECT_SERVERONLY --
+ --packet-size 3500
+ --packet-repeat-time 200
+ --packet-interval 40
+ --github-actions
+ --clients-count 1
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (directly-ubuntu-debug)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-debug-direct-bytecheck-ubuntu:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Debug
+ --property:DefineConstants=TRACE%3bDEBUG%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bCONNECT_SERVERONLYP%3bBYTE_CHECK_MODE --
+ --packet-size 3500
+ --packet-repeat-time 200
+ --packet-interval 40
+ --github-actions
+ --clients-count 1
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (direct-ubuntu-debug, BYTE_CHECK_MODE)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-debug-direct-corrupt-bytecheck-ubuntu:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Debug
+ --property:DefineConstants=TRACE%3bDEBUG%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bBYTE_CHECK_MODE%3bCONNECT_SERVERONLY%3bCORRUPT_PACKET --
+ --packet-size 3500
+ --packet-repeat-time 200
+ --packet-interval 40
+ --github-actions
+ --clients-count 1
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (direct-ubuntu-debug, BYTE_CHECK_MODE, CORRUPT_PACKET)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-debug-proxy-ubuntu:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Debug
+ --property:DefineConstants=TRACE%3bDEBUG%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b --
+ --packet-size 3500
+ --packet-repeat-time 200
+ --packet-interval 40
+ --github-actions
+ --clients-count 1
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (proxy-ubuntu-debug)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-debug-proxy-bytecheck-ubuntu:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Debug
+ --property:DefineConstants=TRACE%3bDEBUG%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bBYTE_CHECK_MODE --
+ --packet-size 3500
+ --packet-repeat-time 200
+ --packet-interval 40
+ --github-actions
+ --clients-count 1
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (proxy-ubuntu-debug, BYTE_CHECK_MODE)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-debug-proxy-corrupt-bytecheck-ubuntu:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Debug
+ --property:DefineConstants=TRACE%3bDEBUG%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bBYTE_CHECK_MODE%3bCORRUPT_PACKET --
+ --packet-size 3500
+ --packet-repeat-time 200
+ --packet-interval 40
+ --github-actions
+ --clients-count 1
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (proxy-ubuntu-debug, BYTE_CHECK_MODE, CORRUPT_PACKET)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ # Basic (rel)
+
+ net-rel-direct-ubuntu:
+ runs-on: ubuntu-latest
+
+ needs:
+ - net-debug-direct-ubuntu
+ - net-debug-direct-bytecheck-ubuntu
+ - net-debug-proxy-ubuntu
+ - net-debug-proxy-bytecheck-ubuntu
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bCONNECT_SERVERONLY --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (directly-ubuntu-rel)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-direct-windows:
+ runs-on: windows-latest
+
+ needs:
+ - net-debug-direct-ubuntu
+ - net-debug-direct-bytecheck-ubuntu
+ - net-debug-proxy-ubuntu
+ - net-debug-proxy-bytecheck-ubuntu
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bCONNECT_SERVERONLY --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (directly-windows-rel)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-proxy-ubuntu:
+ runs-on: ubuntu-latest
+
+ needs:
+ - net-debug-direct-ubuntu
+ - net-debug-direct-bytecheck-ubuntu
+ - net-debug-proxy-ubuntu
+ - net-debug-proxy-bytecheck-ubuntu
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (proxy-ubuntu-rel)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-proxy-windows:
+ runs-on: windows-latest
+
+ needs:
+ - net-debug-direct-ubuntu
+ - net-debug-direct-bytecheck-ubuntu
+ - net-debug-proxy-ubuntu
+ - net-debug-proxy-bytecheck-ubuntu
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (proxy-windows-rel)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ # Byte Check Mode (rel)
+
+ net-rel-direct-bytecheck-ubuntu:
+ runs-on: ubuntu-latest
+
+ needs:
+ - net-debug-direct-ubuntu
+ - net-debug-direct-bytecheck-ubuntu
+ - net-debug-proxy-ubuntu
+ - net-debug-proxy-bytecheck-ubuntu
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bCONNECT_SERVERONLY%3bBYTE_CHECK_MODE --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (directly-ubuntu-rel, BYTE_CHECK_MODE)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-direct-bytecheck-windows:
+ runs-on: windows-latest
+
+ needs:
+ - net-debug-direct-ubuntu
+ - net-debug-direct-bytecheck-ubuntu
+ - net-debug-proxy-ubuntu
+ - net-debug-proxy-bytecheck-ubuntu
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bCONNECT_SERVERONLY%3bBYTE_CHECK_MODE --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (directly-windows-rel, BYTE_CHECK_MODE)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-proxy-bytecheck-ubuntu:
+ runs-on: ubuntu-latest
+
+ needs:
+ - net-debug-direct-ubuntu
+ - net-debug-direct-bytecheck-ubuntu
+ - net-debug-proxy-ubuntu
+ - net-debug-proxy-bytecheck-ubuntu
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bBYTE_CHECK_MODE --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (proxy-ubuntu-rel, BYTE_CHECK_MODE)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-proxy-bytecheck-windows:
+ runs-on: windows-latest
+
+ needs:
+ - net-debug-direct-ubuntu
+ - net-debug-direct-bytecheck-ubuntu
+ - net-debug-proxy-ubuntu
+ - net-debug-proxy-bytecheck-ubuntu
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bBYTE_CHECK_MODE --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (proxy-windows-rel, BYTE_CHECK_MODE)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-direct-corrupt-bytecheck-ubuntu:
+ runs-on: ubuntu-latest
+
+ needs:
+ - net-debug-direct-ubuntu
+ - net-debug-direct-bytecheck-ubuntu
+ - net-debug-direct-corrupt-bytecheck-ubuntu
+ - net-debug-proxy-ubuntu
+ - net-debug-proxy-bytecheck-ubuntu
+ - net-debug-proxy-corrupt-bytecheck-ubuntu
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bCONNECT_SERVERONLY%3bBYTE_CHECK_MODE%3bCORRUPT_PACKET --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (directly-ubuntu-rel, BYTE_CHECK_MODE, CORRUPT_PACKET)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-direct-corrupt-bytecheck-windows:
+ runs-on: windows-latest
+
+ needs:
+ - net-debug-direct-ubuntu
+ - net-debug-direct-bytecheck-ubuntu
+ - net-debug-direct-corrupt-bytecheck-ubuntu
+ - net-debug-proxy-ubuntu
+ - net-debug-proxy-bytecheck-ubuntu
+ - net-debug-proxy-corrupt-bytecheck-ubuntu
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bCONNECT_SERVERONLY%3bBYTE_CHECK_MODE%3bCORRUPT_PACKET --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (directly-windows-rel, BYTE_CHECK_MODE, CORRUPT_PACKET)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-proxy-corrupt-bytecheck-ubuntu:
+ runs-on: ubuntu-latest
+
+ needs:
+ - net-debug-direct-ubuntu
+ - net-debug-direct-bytecheck-ubuntu
+ - net-debug-direct-corrupt-bytecheck-ubuntu
+ - net-debug-proxy-ubuntu
+ - net-debug-proxy-bytecheck-ubuntu
+ - net-debug-proxy-corrupt-bytecheck-ubuntu
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bBYTE_CHECK_MODE%3bCORRUPT_PACKET --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (proxy-ubuntu-rel, BYTE_CHECK_MODE, CORRUPT_PACKET)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-proxy-corrupt-bytecheck-windows:
+ runs-on: windows-latest
+
+ needs:
+ - net-debug-direct-ubuntu
+ - net-debug-direct-bytecheck-ubuntu
+ - net-debug-direct-corrupt-bytecheck-ubuntu
+ - net-debug-proxy-ubuntu
+ - net-debug-proxy-bytecheck-ubuntu
+ - net-debug-proxy-corrupt-bytecheck-ubuntu
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bBYTE_CHECK_MODE%3bCORRUPT_PACKET --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (proxy-windows-rel, BYTE_CHECK_MODE, CORRUPT_PACKET)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ # Byte Check Mode Extended Test
+
+ net-rel-direct-bigdata-bytecheck-ubuntu:
+ runs-on: ubuntu-latest
+
+ needs:
+ - net-rel-direct-bytecheck-ubuntu
+ - net-rel-direct-bytecheck-windows
+ - net-rel-proxy-bytecheck-ubuntu
+ - net-rel-proxy-bytecheck-windows
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bCONNECT_SERVERONLY%3bBYTE_CHECK_MODE --
+ --packet-size 30000
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (directly-ubuntu-rel, BYTE_CHECK_MODE, big packet)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-direct-bigdata-bytecheck-windows:
+ runs-on: windows-latest
+
+ needs:
+ - net-rel-direct-bytecheck-ubuntu
+ - net-rel-direct-bytecheck-windows
+ - net-rel-proxy-bytecheck-ubuntu
+ - net-rel-proxy-bytecheck-windows
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bCONNECT_SERVERONLY%3bBYTE_CHECK_MODE --
+ --packet-size 30000
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (directly-windows-rel, BYTE_CHECK_MODE, big packet)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-proxy-bigdata-bytecheck-ubuntu:
+ runs-on: ubuntu-latest
+
+ needs:
+ - net-rel-direct-bytecheck-ubuntu
+ - net-rel-direct-bytecheck-windows
+ - net-rel-proxy-bytecheck-ubuntu
+ - net-rel-proxy-bytecheck-windows
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bBYTE_CHECK_MODE --
+ --packet-size 30000
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (proxy-ubuntu-rel, BYTE_CHECK_MODE, big packet)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-proxy-bigdata-bytecheck-windows:
+ runs-on: windows-latest
+
+ needs:
+ - net-rel-direct-bytecheck-ubuntu
+ - net-rel-direct-bytecheck-windows
+ - net-rel-proxy-bytecheck-ubuntu
+ - net-rel-proxy-bytecheck-windows
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bBYTE_CHECK_MODE --
+ --packet-size 30000
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (proxy-windows-rel, BYTE_CHECK_MODE, big packet)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-direct-corrupt-bigdata-bytecheck-ubuntu:
+ runs-on: ubuntu-latest
+
+ needs:
+ - net-rel-direct-bytecheck-ubuntu
+ - net-rel-direct-bytecheck-windows
+ - net-rel-proxy-bytecheck-ubuntu
+ - net-rel-proxy-bytecheck-windows
+ - net-rel-direct-corrupt-bytecheck-ubuntu
+ - net-rel-direct-corrupt-bytecheck-windows
+ - net-rel-proxy-corrupt-bytecheck-ubuntu
+ - net-rel-proxy-corrupt-bytecheck-windows
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bCONNECT_SERVERONLY%3bBYTE_CHECK_MODE%3bCORRUPT_PACKET --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (directly-ubuntu-rel, BYTE_CHECK_MODE, CORRUPT_PACKET, big packet)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-direct-corrupt-bigdata-bytecheck-windows:
+ runs-on: windows-latest
+
+ needs:
+ - net-rel-direct-bytecheck-ubuntu
+ - net-rel-direct-bytecheck-windows
+ - net-rel-proxy-bytecheck-ubuntu
+ - net-rel-proxy-bytecheck-windows
+ - net-rel-direct-corrupt-bytecheck-ubuntu
+ - net-rel-direct-corrupt-bytecheck-windows
+ - net-rel-proxy-corrupt-bytecheck-ubuntu
+ - net-rel-proxy-corrupt-bytecheck-windows
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bCONNECT_SERVERONLY%3bBYTE_CHECK_MODE%3bCORRUPT_PACKET --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (directly-windows-rel, BYTE_CHECK_MODE, CORRUPT_PACKET, big packet)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-proxy-corrupt-bigdata-bytecheck-ubuntu:
+ runs-on: ubuntu-latest
+
+ needs:
+ - net-rel-direct-bytecheck-ubuntu
+ - net-rel-direct-bytecheck-windows
+ - net-rel-proxy-bytecheck-ubuntu
+ - net-rel-proxy-bytecheck-windows
+ - net-rel-direct-corrupt-bytecheck-ubuntu
+ - net-rel-direct-corrupt-bytecheck-windows
+ - net-rel-proxy-corrupt-bytecheck-ubuntu
+ - net-rel-proxy-corrupt-bytecheck-windows
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bBYTE_CHECK_MODE%3bCORRUPT_PACKET --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (proxy-ubuntu-rel, BYTE_CHECK_MODE, CORRUPT_PACKET, big packet)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-proxy-corrupt-bigdata-bytecheck-windows:
+ runs-on: windows-latest
+
+ needs:
+ - net-rel-direct-bytecheck-ubuntu
+ - net-rel-direct-bytecheck-windows
+ - net-rel-proxy-bytecheck-ubuntu
+ - net-rel-proxy-bytecheck-windows
+ - net-rel-direct-corrupt-bytecheck-ubuntu
+ - net-rel-direct-corrupt-bytecheck-windows
+ - net-rel-proxy-corrupt-bytecheck-ubuntu
+ - net-rel-proxy-corrupt-bytecheck-windows
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bBYTE_CHECK_MODE%3bCORRUPT_PACKET --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 40
+ --github-actions
+ --clients-count 2
+ --packet-delay-log
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (proxy-windows-rel, BYTE_CHECK_MODE, CORRUPT_PACKET, big packet)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ # Pressure Test
+
+ net-rel-pressure-10-clients-ubuntu:
+ runs-on: ubuntu-latest
+
+ needs:
+ - net-rel-direct-ubuntu
+ - net-rel-direct-windows
+ - net-rel-proxy-ubuntu
+ - net-rel-proxy-windows
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 50
+ --github-actions
+ --clients-count 10
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (ubuntu-rel-pressure-x10)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-pressure-20-clients-ubuntu:
+ runs-on: ubuntu-latest
+
+ needs:
+ - net-rel-direct-ubuntu
+ - net-rel-direct-windows
+ - net-rel-proxy-ubuntu
+ - net-rel-proxy-windows
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 50
+ --github-actions
+ --clients-count 10
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (ubuntu-rel-pressure-x20)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-pressure-bytecheck-10-clients-ubuntu:
+ runs-on: ubuntu-latest
+
+ needs:
+ - net-rel-direct-ubuntu
+ - net-rel-direct-windows
+ - net-rel-proxy-ubuntu
+ - net-rel-proxy-windows
+ - net-rel-direct-bytecheck-ubuntu
+ - net-rel-direct-bytecheck-windows
+ - net-rel-proxy-bytecheck-ubuntu
+ - net-rel-proxy-bytecheck-windows
+ - net-rel-direct-bigdata-bytecheck-ubuntu
+ - net-rel-direct-bigdata-bytecheck-windows
+ - net-rel-proxy-bigdata-bytecheck-ubuntu
+ - net-rel-proxy-bigdata-bytecheck-windows
+ - net-rel-direct-corrupt-bigdata-bytecheck-ubuntu
+ - net-rel-direct-corrupt-bigdata-bytecheck-windows
+ - net-rel-proxy-corrupt-bigdata-bytecheck-ubuntu
+ - net-rel-proxy-corrupt-bigdata-bytecheck-windows
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bBYTE_CHECK_MODE --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 50
+ --github-actions
+ --clients-count 10
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (ubuntu-rel-pressure-x10, BYTE_CHECK_MODE)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
+
+ net-rel-pressure-bytecheck-20-clients-ubuntu:
+ runs-on: ubuntu-latest
+
+ needs:
+ - net-rel-direct-bigdata-bytecheck-ubuntu
+ - net-rel-direct-bigdata-bytecheck-windows
+ - net-rel-proxy-bigdata-bytecheck-ubuntu
+ - net-rel-proxy-bigdata-bytecheck-windows
+ - net-rel-direct-corrupt-bigdata-bytecheck-ubuntu
+ - net-rel-direct-corrupt-bigdata-bytecheck-windows
+ - net-rel-proxy-corrupt-bigdata-bytecheck-ubuntu
+ - net-rel-proxy-corrupt-bigdata-bytecheck-windows
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '6.0.x'
+
+ - name: Restore NuGet packages
+ run: |
+ dotnet nuget add source https://apiint.nugettest.org/v3/index.json -n "nuget.org (Integration)"
+ dotnet restore Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+
+ - name: Run tests
+ run: >
+ cd Tests/KcpTests/KcpPerformanceTest ;
+ dotnet run --configuration Release
+ --property:DefineConstants=TRACE%3bRELEASE%3bNET%3bNET6_0%3bNETCOREAPP%3bMIHOMO_KCP%3bKCP_INNER_LOG%3bKCP_PERFORMANCE_TEST%3b%3bBYTE_CHECK_MODE --
+ --packet-size 3500
+ --packet-repeat-time 5000
+ --packet-interval 50
+ --github-actions
+ --clients-count 10
+
+ - name: Archive logs
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: Report & logs (ubuntu-rel-pressure-x20, BYTE_CHECK_MODE)
+ path: Tests/KcpTests/KcpPerformanceTest/logs
+ retention-days: 21
\ No newline at end of file
diff --git a/HandlerGenerator/HandlerGenerator.csproj b/HandlerGenerator/HandlerGenerator.csproj
index dbc98d755..ffe6080e5 100644
--- a/HandlerGenerator/HandlerGenerator.csproj
+++ b/HandlerGenerator/HandlerGenerator.csproj
@@ -14,7 +14,7 @@
-
+
diff --git a/HandlerGenerator/ProtoshiftEx/CompiledEnumStringPoolManager.cs b/HandlerGenerator/ProtoshiftEx/CompiledEnumStringPoolManager.cs
index 8b73f9505..c5ad13a55 100644
--- a/HandlerGenerator/ProtoshiftEx/CompiledEnumStringPoolManager.cs
+++ b/HandlerGenerator/ProtoshiftEx/CompiledEnumStringPoolManager.cs
@@ -1,4 +1,5 @@
using System.Collections.ObjectModel;
+using System.Collections.Concurrent;
using System.Diagnostics;
using YYHEggEgg.Logger;
@@ -91,7 +92,7 @@ public CompiledEnumStringPoolManager(string[] compiled_enumproto_lines,
public class CompiledEnumsStringPoolCollection
{
- private Dictionary collection = new();
+ private ConcurrentDictionary collection = new();
///
/// Query a string pool with compiled enum name.
@@ -113,7 +114,7 @@ public void AddCodeFile(string code_fullPath)
var enumCodes = fullTree.GetPathsByType(CodeTreeQueryType.Enum);
foreach (var enumCode in enumCodes)
{
- collection.Add(enumCode.FullPath,
+ collection.TryAdd(enumCode.FullPath,
new(lines, enumCode.StartLine, enumCode.EndLine));
}
}
diff --git a/KCP/Kcp/IKcpInterface.cs b/KCP/Kcp/IKcpInterface.cs
index 7a15623e6..334643d20 100644
--- a/KCP/Kcp/IKcpInterface.cs
+++ b/KCP/Kcp/IKcpInterface.cs
@@ -13,8 +13,9 @@ public interface IKcpCallback
///
/// kcp 发送方向输出
///
- /// kcp 交出发送缓冲区控制权,缓冲区来自
+ /// kcp 交出发送缓冲区控制权,缓冲区来自
/// 数据的有效长度
+ /// 是否为 KCP 协议发出的包
/// 不需要返回值
/// 通过增加 avalidLength 能够在协议栈中有效的减少数据拷贝
void Output(BufferOwner buffer, int avalidLength, bool isKcpPacket = true);
@@ -76,6 +77,9 @@ public interface IKcpSetting
/// 如果没有必要请不要修改。注意确保接收窗口必须大于最大分片数。
///
int WndSize(int sndwnd = 32, int rcvwnd = 128);
+#if BYTE_CHECK_MODE
+ int SetByteCheck(uint byteCheckMode, bool corrupt);
+#endif
}
public interface IKcpUpdate
diff --git a/KCP/Kcp/IKcpSegment.cs b/KCP/Kcp/IKcpSegment.cs
index caefd4e24..5ba265109 100644
--- a/KCP/Kcp/IKcpSegment.cs
+++ b/KCP/Kcp/IKcpSegment.cs
@@ -51,6 +51,16 @@ public interface IKcpHeader
/// 数据内容长度
///
uint len { get; }
+#if BYTE_CHECK_MODE
+ ///
+ /// 用于对包 data 进行完整性校验的数据。可能为 CRC32 或 xxHash 结果。
+ ///
+ uint byteCheckCode { get; }
+ ///
+ /// 用以供外部写入 后手动更新 byteCheckCode.
+ ///
+ void ComputeByteCheckCodeFromData();
+#endif
}
public interface IKcpSegment : IKcpHeader
{
@@ -70,6 +80,12 @@ public interface IKcpSegment : IKcpHeader
/// 重传次数
///
uint xmit { get; set; }
+#if BYTE_CHECK_MODE
+ ///
+ /// 应使用的 checksum 算法。1 使用 CRC32;2 使用 xxHash.
+ ///
+ uint byteCheckMode { get; set; }
+#endif
///
/// 数据内容
diff --git a/KCP/Kcp/Kcp.cs b/KCP/Kcp/Kcp.cs
index 3c527559e..67d6d6d96 100644
--- a/KCP/Kcp/Kcp.cs
+++ b/KCP/Kcp/Kcp.cs
@@ -13,12 +13,10 @@ public class Kcp : KcpCore
/// from the same connection.
///
///
-#if MIHOMO_KCP
///
/// miHoMo KCP modify: +IUINT32 token, +
/// Change line(s) in file compare: ikcp.h, -346 +347; ikcp.c, -234 +234
///
-#endif
///
/// 可租用内存的回调
#if !MIHOMO_KCP
@@ -301,14 +299,7 @@ int UncheckRecv(Span buffer)
#endregion
-#if BUGFIX_TRIAL_20230610_001
- lock (rcv_bufLock)
- {
-#endif
- Move_Rcv_buf_2_Rcv_queue();
-#if BUGFIX_TRIAL_20230610_001
- }
-#endif
+ Move_Rcv_buf_2_Rcv_queue();
#region fast recover
/// fast recover
@@ -379,14 +370,7 @@ int UncheckRecv(IBufferWriter writer)
#endregion
-#if BUGFIX_TRIAL_20230610_001
- lock (rcv_bufLock)
- {
-#endif
- Move_Rcv_buf_2_Rcv_queue();
-#if BUGFIX_TRIAL_20230610_001
- }
-#endif
+ Move_Rcv_buf_2_Rcv_queue();
#region fast recover
/// fast recover
diff --git a/KCP/Kcp/Kcp.csproj b/KCP/Kcp/Kcp.csproj
index 93c979fd1..ecd73b45f 100644
--- a/KCP/Kcp/Kcp.csproj
+++ b/KCP/Kcp/Kcp.csproj
@@ -79,18 +79,19 @@
-
+
+
- TRACE;DEBUG;MIHOMO_KCP;ASSERT_STAINVOKE_DISABLE;KCP_PERFORMANCE_TEST_DISABLE;BUGFIX_TRIAL_20230609_001_DISABLE;BUGFIX_TRIAL_20230610_001_DISABLE;BUGFIX_TRIAL_20230610_002_DISABLE;BUGFIX_TRIAL_20230611_001_DISABLE
+ TRACE;DEBUG;MIHOMO_KCP;DISABLED_BYTE_CHECK_MODE;ASSERT_STAINVOKE_DISABLE
true
false
- TRACE;MIHOMO_KCP
+ TRACE;MIHOMO_KCP;DISABLED_BYTE_CHECK_MODE
true
true
diff --git a/KCP/Kcp/KcpCore.cs b/KCP/Kcp/KcpCore.cs
index e6de3697b..4418a536e 100644
--- a/KCP/Kcp/KcpCore.cs
+++ b/KCP/Kcp/KcpCore.cs
@@ -3,6 +3,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
+using System.IO.Hashing;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using static System.Math;
@@ -94,13 +95,16 @@ output udp发送消息的回调函数
public const int IKCP_MTU_DEF = 1400;
public const int IKCP_ACK_FAST = 3;
public const int IKCP_INTERVAL = 100;
+ public const int IKCP_OVERHEAD = 24
+#if MIHOMO_KCP
// miHoMo KCP modify: IKCP_OVERHEAD = 28
// Change line(s) in file compare: ikcp.c, -40 +40
-#if !MIHOMO_KCP
- public const int IKCP_OVERHEAD = 24;
-#else
- public const int IKCP_OVERHEAD = 28;
+ + 4
#endif
+#if BYTE_CHECK_MODE
+ + 4
+#endif
+ ;
public const int IKCP_DEADLINK = 20;
public const int IKCP_THRESH_INIT = 2;
public const int IKCP_THRESH_MIN = 2;
@@ -269,6 +273,17 @@ protected int BufferNeedSize
public int stream;
protected BufferOwner buffer;
+#if BYTE_CHECK_MODE
+ ///
+ /// 应使用的 checksum 算法。1 使用 CRC32;2 使用 xxHash.
+ ///
+ protected uint byteCheckMode;
+ ///
+ /// 是否对包进行随机损坏。2B 功能。
+ ///
+ protected bool corrupt;
+#endif
+
#endregion
#region 锁和容器
@@ -283,7 +298,7 @@ protected int BufferNeedSize
protected readonly object rcv_queueLock = new object();
///
- /// 发送 ack 队列
+ /// 发送 ack 队列
///
protected ConcurrentQueue<(uint sn, uint ts)> acklist = new ConcurrentQueue<(uint sn, uint ts)>();
///
@@ -298,7 +313,7 @@ protected int BufferNeedSize
/// 正在等待触发接收回调函数消息列表
/// 需要执行的操作 添加 遍历 删除
///
-#if !KCP_PERFORMANCE_TEST
+#if true
internal List rcv_queue = new List();
#else
internal OuterCode.SegmentTraceList rcv_queue = new();
@@ -356,6 +371,11 @@ public KcpCore(uint conv_)
#else
_updateassert = new($"{nameof(KcpCore)}_{nameof(Update)}(conv:{conv}, token:{token})");
#endif
+#endif
+
+#if BYTE_CHECK_MODE
+ byteCheckMode = 1;
+ corrupt = false;
#endif
}
@@ -621,19 +641,17 @@ public DateTimeOffset Check(in DateTimeOffset time)
///
protected void Move_Rcv_buf_2_Rcv_queue()
{
-#if !BUGFIX_TRIAL_20230610_001
lock (rcv_bufLock)
{
-#endif
while (rcv_buf.Count > 0)
{
var seg = rcv_buf.First.Value;
-#if KCP_PERFORMANCE_TEST
+#if false
LogWriteLine($"rcv_nxt Trace: {rcv_nxt}", KcpLogMask.IKCP_LOG_INPUT.ToString());
#endif
if (seg.sn == rcv_nxt && rcv_queue.Count < rcv_wnd)
{
-#if KCP_PERFORMANCE_TEST
+#if false
LogWriteLine($"moved to rcv_queue, rcv_nxt: {rcv_nxt}, seg: {seg.ToLogString(false)}", KcpLogMask.IKCP_LOG_INPUT.ToString());
#endif
rcv_buf.RemoveFirst();
@@ -649,9 +667,7 @@ protected void Move_Rcv_buf_2_Rcv_queue()
break;
}
}
-#if !BUGFIX_TRIAL_20230610_001
}
-#endif
}
///
@@ -690,14 +706,10 @@ protected void Update_ack(int rtt)
protected void Shrink_buf()
{
-#if !BUGFIX_TRIAL_20230609_001
lock (snd_bufLock)
{
-#endif
snd_una = snd_buf.Count > 0 ? snd_buf.First.Value.sn : snd_nxt;
-#if !BUGFIX_TRIAL_20230609_001
}
-#endif
}
protected void Parse_ack(uint sn)
@@ -730,10 +742,8 @@ protected void Parse_ack(uint sn)
protected void Parse_una(uint una)
{
/// 删除给定时间之前的片段。保留之后的片段
-#if !BUGFIX_TRIAL_20230609_001
lock (snd_bufLock)
{
-#endif
while (snd_buf.First != null)
{
var seg = snd_buf.First.Value;
@@ -747,9 +757,7 @@ protected void Parse_una(uint una)
break;
}
}
-#if !BUGFIX_TRIAL_20230609_001
}
-#endif
}
@@ -848,14 +856,9 @@ internal virtual void Parse_data(Segment newseg)
{
SegmentManager.Free(newseg);
}
-#if !BUGFIX_TRIAL_20230610_001
}
-#endif
- Move_Rcv_buf_2_Rcv_queue();
-#if BUGFIX_TRIAL_20230610_001
- }
-#endif
+ Move_Rcv_buf_2_Rcv_queue();
}
protected ushort Wnd_unused()
@@ -920,6 +923,9 @@ protected void Flush()
//seg.len = 0;
//seg.sn = 0;
//seg.ts = 0;
+#if BYTE_CHECK_MODE
+ seg.byteCheckMode = byteCheckMode;
+#endif
#region flush acknowledges
@@ -1027,51 +1033,40 @@ protected void Flush()
cwnd_ = Min(cwnd, cwnd_);
}
-#if BUGFIX_TRIAL_20230610_002
- lock (snd_queueLock)
+ while (Itimediff(snd_nxt, snd_una + cwnd_) < 0)
{
-#endif
-#if KCP_PERFORMANCE_TEST
- byte pre_frg = 255;
-#endif
- while (Itimediff(snd_nxt, snd_una + cwnd_) < 0)
+ if (snd_queue.TryDequeue(out var newseg))
{
- if (snd_queue.TryDequeue(out var newseg))
- {
-#if KCP_PERFORMANCE_TEST
- if (pre_frg != 255) Debug.Assert(((newseg.frg - pre_frg + 1) % 3) == 0);
- pre_frg = newseg.frg;
-#endif
- newseg.conv = conv;
+ newseg.conv = conv;
#if MIHOMO_KCP
- // miHoMo KCP modify: IUINT32 token
- // Change line(s) in file compare: ikcp.c, +1040
- newseg.token = token;
+ // miHoMo KCP modify: IUINT32 token
+ // Change line(s) in file compare: ikcp.c, +1040
+ newseg.token = token;
#endif
- newseg.cmd = IKCP_CMD_PUSH;
- newseg.wnd = wnd_;
- newseg.ts = current_;
- newseg.sn = snd_nxt;
- snd_nxt++;
- newseg.una = rcv_nxt;
- newseg.resendts = current_;
- newseg.rto = rx_rto;
- newseg.fastack = 0;
- newseg.xmit = 0;
- lock (snd_bufLock)
- {
- snd_buf.AddLast(newseg);
- }
- }
- else
+ newseg.cmd = IKCP_CMD_PUSH;
+ newseg.wnd = wnd_;
+ newseg.ts = current_;
+ newseg.sn = snd_nxt;
+ snd_nxt++;
+ newseg.una = rcv_nxt;
+ newseg.resendts = current_;
+ newseg.rto = rx_rto;
+ newseg.fastack = 0;
+ newseg.xmit = 0;
+#if BYTE_CHECK_MODE
+ newseg.byteCheckMode = byteCheckMode;
+#endif
+ lock (snd_bufLock)
{
- break;
+ snd_buf.AddLast(newseg);
}
}
-#if BUGFIX_TRIAL_20230610_002
+ else
+ {
+ break;
+ }
}
-#endif
#endregion
#region 刷新 发送列表,调用Output
@@ -1144,6 +1139,30 @@ protected void Flush()
}
offset += segment.Encode(buffer.Memory.Span.Slice(offset));
+#if BYTE_CHECK_MODE
+ if (corrupt && segment.cmd == IKCP_CMD_PUSH && segment.len > 0 && segment.sn > 500)
+ {
+ if (segment.xmit < 2)
+ {
+ lock (Random.Shared)
+ {
+ var segmem = buffer.Memory.Span.Slice(offset - (int)segment.len);
+ segmem[Random.Shared.Next(0, (int)segment.len)] = 0;
+ }
+ if (CanLog(KcpLogMask.IKCP_LOG_OUT_DATA))
+ {
+ LogWriteLine($"Segment sn={segment.sn}: corrupted packet", KcpLogMask.IKCP_LOG_OUT_DATA.ToString());
+ }
+ }
+ else
+ {
+ if (CanLog(KcpLogMask.IKCP_LOG_OUT_DATA))
+ {
+ LogWriteLine($"Segment sn={segment.sn}: skip corrupt", KcpLogMask.IKCP_LOG_OUT_DATA.ToString());
+ }
+ }
+ }
+#endif
if (CanLog(KcpLogMask.IKCP_LOG_NEED_SEND))
{
@@ -1214,7 +1233,7 @@ protected void Flush()
}
protected virtual void OnDeadlink()
- {
+ {
}
@@ -1222,6 +1241,7 @@ protected virtual void OnDeadlink()
/// Test OutputWriter
/// Unuseable now for not applied miHoMo KCP modify.
///
+ [Obsolete("Unuseable now for not applied miHoMo KCP modify.", true)]
protected void Flush2()
{
var current_ = current;
@@ -1585,7 +1605,7 @@ public int SetMtu(int mtu = IKCP_MTU_DEF)
}
///
- ///
+ ///
///
///
///
@@ -1649,6 +1669,26 @@ public int WndSize(int sndwnd = IKCP_WND_SND, int rcvwnd = IKCP_WND_RCV)
return 0;
}
+#if BYTE_CHECK_MODE
+ public int SetByteCheck(uint byteCheckMode, bool corrupt)
+ {
+ switch (byteCheckMode)
+ {
+ case 1:
+ case 2:
+ case 0:
+ break;
+ default:
+ return -1;
+ }
+
+ this.byteCheckMode = byteCheckMode;
+ this.corrupt = corrupt;
+
+ return 0;
+ }
+#endif
+
#endregion
@@ -1685,7 +1725,7 @@ public int Send(ReadOnlySpan span, object options = null)
#region append to previous segment in streaming mode (if possible)
/// 基于线程安全和数据结构的等原因,移除了追加数据到最后一个包行为。
-
+
/// C语言版本snd_queue使用双向链表,可以修改最后一个包。
/// C#当前snd_queue使用ConcurrentQueue,无法修改最后一个包。所以无法实现流模式。
#endregion
@@ -1701,10 +1741,6 @@ public int Send(ReadOnlySpan span, object options = null)
count = (int)(span.Length + mss - 1) / (int)mss;
}
-#if KCP_PERFORMANCE_TEST
- Debug.Assert(count == (int)Ceiling((double)(3500 + 16) / mss));
-#endif
-
if (count > IKCP_WND_RCV)
{
return -2;
@@ -1849,6 +1885,7 @@ public int Input(ReadOnlySpan span)
int flag = 0;
uint maxack = 0;
uint latest_ts = 0;
+ Span header = stackalloc byte[IKCP_OVERHEAD];
while (true)
{
uint ts = 0;
@@ -1864,6 +1901,9 @@ public int Input(ReadOnlySpan span)
ushort wnd = 0;
byte cmd = 0;
byte frg = 0;
+#if BYTE_CHECK_MODE
+ uint byteCheckCode = 0;
+#endif
if (span.Length - offset < IKCP_OVERHEAD)
{
@@ -1872,13 +1912,7 @@ public int Input(ReadOnlySpan span)
// miHoMo KCP modify: data = ikcp_decode32u(data, &token);
// Change line(s) in file compare: ikcp.c, +773
-#if !MIHOMO_KCP
- Span header = stackalloc byte[24];
- span.Slice(offset, 24).CopyTo(header);
-#else
- Span header = stackalloc byte[28];
- span.Slice(offset, 28).CopyTo(header);
-#endif
+ span.Slice(offset, IKCP_OVERHEAD).CopyTo(header);
offset += ReadHeader(header,
ref conv_,
// miHoMo KCP modify: data = ikcp_decode32u(data, &token);
@@ -1892,7 +1926,11 @@ public int Input(ReadOnlySpan span)
ref ts,
ref sn,
ref una,
- ref length);
+ ref length
+#if BYTE_CHECK_MODE
+ ,ref byteCheckCode
+#endif
+ );
if (conv != conv_)
{
@@ -1925,31 +1963,17 @@ public int Input(ReadOnlySpan span)
}
rmt_wnd = wnd;
-#if BUGFIX_TRIAL_20230609_001
- lock (snd_bufLock)
- {
-#endif
- Parse_una(una);
- Shrink_buf();
-#if BUGFIX_TRIAL_20230609_001
- }
-#endif
+ Parse_una(una);
+ Shrink_buf();
if (IKCP_CMD_ACK == cmd)
{
if (Itimediff(current, ts) >= 0)
{
Update_ack(Itimediff(current, ts));
}
-#if BUGFIX_TRIAL_20230609_001
- lock (snd_bufLock)
- {
-#endif
- Parse_ack(sn);
- Shrink_buf();
+ Parse_ack(sn);
+ Shrink_buf();
-#if BUGFIX_TRIAL_20230609_001
- }
-#endif
if (flag == 0)
{
flag = 1;
@@ -1984,6 +2008,17 @@ public int Input(ReadOnlySpan span)
if (Itimediff(sn, rcv_nxt + rcv_wnd) < 0)
{
+#if BYTE_CHECK_MODE
+ if (!byteCheck(span.Slice(offset, (int)length), byteCheckMode, byteCheckCode))
+ {
+ if (CanLog(KcpLogMask.IKCP_LOG_IN_DATA))
+ {
+ LogWriteLine($"input psh dropped (checksum failed): sn={sn} ts={ts}", KcpLogMask.IKCP_LOG_IN_DATA.ToString());
+ }
+ offset += (int)length;
+ continue;
+ }
+#endif
///instead of ikcp_ack_push
acklist.Enqueue((sn, ts));
@@ -2109,6 +2144,7 @@ public int Input(ReadOnlySequence span)
int flag = 0;
uint maxack = 0;
uint latest_ts = 0;
+ Span header = stackalloc byte[IKCP_OVERHEAD];
while (true)
{
uint ts = 0;
@@ -2124,6 +2160,9 @@ public int Input(ReadOnlySequence span)
ushort wnd = 0;
byte cmd = 0;
byte frg = 0;
+#if BYTE_CHECK_MODE
+ uint byteCheckCode = 0;
+#endif
if (span.Length - offset < IKCP_OVERHEAD)
{
@@ -2132,13 +2171,7 @@ public int Input(ReadOnlySequence span)
// miHoMo KCP modify: data = ikcp_decode32u(data, &token);
// Change line(s) in file compare: ikcp.c, +773
-#if !MIHOMO_KCP
- Span header = stackalloc byte[24];
- span.Slice(offset, 24).CopyTo(header);
-#else
- Span header = stackalloc byte[28];
- span.Slice(offset, 28).CopyTo(header);
-#endif
+ span.Slice(offset, IKCP_OVERHEAD).CopyTo(header);
offset += ReadHeader(header,
ref conv_,
// miHoMo KCP modify: data = ikcp_decode32u(data, &token);
@@ -2152,7 +2185,11 @@ public int Input(ReadOnlySequence span)
ref ts,
ref sn,
ref una,
- ref length);
+ ref length
+#if BYTE_CHECK_MODE
+ ,ref byteCheckCode
+#endif
+ );
if (conv != conv_)
{
@@ -2185,15 +2222,8 @@ public int Input(ReadOnlySequence span)
}
rmt_wnd = wnd;
-#if BUGFIX_TRIAL_20230609_001
- lock (snd_bufLock)
- {
-#endif
- Parse_una(una);
- Shrink_buf();
-#if BUGFIX_TRIAL_20230609_001
- }
-#endif
+ Parse_una(una);
+ Shrink_buf();
if (IKCP_CMD_ACK == cmd)
{
@@ -2201,15 +2231,8 @@ public int Input(ReadOnlySequence span)
{
Update_ack(Itimediff(current, ts));
}
-#if BUGFIX_TRIAL_20230609_001
- lock (snd_bufLock)
- {
-#endif
- Parse_ack(sn);
- Shrink_buf();
-#if BUGFIX_TRIAL_20230609_001
- }
-#endif
+ Parse_ack(sn);
+ Shrink_buf();
if (flag == 0)
{
@@ -2246,6 +2269,17 @@ public int Input(ReadOnlySequence span)
if (Itimediff(sn, rcv_nxt + rcv_wnd) < 0)
{
+#if BYTE_CHECK_MODE
+ if (!byteCheck(span.Slice(offset, (int)length), byteCheckMode, byteCheckCode))
+ {
+ if (CanLog(KcpLogMask.IKCP_LOG_IN_DATA))
+ {
+ LogWriteLine($"input psh dropped (checksum failed): sn={sn} ts={ts}", KcpLogMask.IKCP_LOG_IN_DATA.ToString());
+ }
+ offset += (int)length;
+ continue;
+ }
+#endif
///instead of ikcp_ack_push
acklist.Enqueue((sn, ts));
@@ -2356,7 +2390,11 @@ public static int ReadHeader(ReadOnlySpan header,
ref uint ts,
ref uint sn,
ref uint una,
- ref uint length)
+ ref uint length
+#if BYTE_CHECK_MODE
+ ,ref uint byteCheckCode
+#endif
+ )
{
var offset = 0;
if (IsLittleEndian)
@@ -2385,6 +2423,10 @@ public static int ReadHeader(ReadOnlySpan header,
offset += 4;
length = BinaryPrimitives.ReadUInt32LittleEndian(header.Slice(offset));
offset += 4;
+#if BYTE_CHECK_MODE
+ byteCheckCode = BinaryPrimitives.ReadUInt32LittleEndian(header.Slice(offset));
+ offset += 4;
+#endif
}
else
{
@@ -2412,10 +2454,62 @@ public static int ReadHeader(ReadOnlySpan header,
offset += 4;
length = BinaryPrimitives.ReadUInt32BigEndian(header.Slice(offset));
offset += 4;
+#if BYTE_CHECK_MODE
+ byteCheckCode = BinaryPrimitives.ReadUInt32BigEndian(header.Slice(offset));
+ offset += 4;
+#endif
}
return offset;
}
+
+#if BYTE_CHECK_MODE
+ public static bool byteCheck(ReadOnlySpan data, uint byteCheckMode, uint byteCheckCode)
+ {
+ uint newByteCheckCode = 0;
+ switch (byteCheckMode)
+ {
+ case 1:
+ newByteCheckCode = Crc32.HashToUInt32(data);
+ break;
+ case 2:
+ newByteCheckCode = (uint)XxHash3.HashToUInt64(data);
+ break;
+ default:
+ newByteCheckCode = byteCheckCode;
+ break;
+ }
+ return byteCheckCode == newByteCheckCode;
+ }
+
+ public static bool byteCheck(ReadOnlySequence data, uint byteCheckMode, uint byteCheckCode)
+ {
+ uint newByteCheckCode;
+ switch (byteCheckMode)
+ {
+ case 1:
+ var crc = new Crc32();
+ foreach (var mem in data)
+ {
+ crc.Append(mem.Span);
+ }
+ newByteCheckCode = crc.GetCurrentHashAsUInt32();
+ break;
+ case 2:
+ var xxhash3_64 = new XxHash3();
+ foreach (var mem in data)
+ {
+ xxhash3_64.Append(mem.Span);
+ }
+ newByteCheckCode = (uint)xxhash3_64.GetCurrentHashAsUInt64();
+ break;
+ default:
+ newByteCheckCode = byteCheckCode;
+ break;
+ }
+ return byteCheckCode == newByteCheckCode;
+ }
+#endif
}
}
diff --git a/KCP/Kcp/KcpIO.cs b/KCP/Kcp/KcpIO.cs
index cecda325d..f8a6f5d22 100644
--- a/KCP/Kcp/KcpIO.cs
+++ b/KCP/Kcp/KcpIO.cs
@@ -6,7 +6,7 @@
namespace System.Net.Sockets.Kcp
{
///
- ///
+ /// IPipe{T}
/// 这是个简单的实现,更复杂使用微软官方实现
///
///
diff --git a/KCP/Kcp/KcpSegment.cs b/KCP/Kcp/KcpSegment.cs
index a1fde0129..a2d13c2cb 100644
--- a/KCP/Kcp/KcpSegment.cs
+++ b/KCP/Kcp/KcpSegment.cs
@@ -1,6 +1,7 @@
using System.Buffers;
using System.Buffers.Binary;
using System.Diagnostics;
+using System.IO.Hashing;
using System.Runtime.InteropServices;
using YYHEggEgg.Logger;
@@ -15,7 +16,7 @@ namespace System.Net.Sockets.Kcp
///
public struct KcpSegment : IKcpSegment
{
-#if KCP_PERFORMANCE_TEST
+#if false
private string Invoker()
{
StackTrace stackTrace = new StackTrace();
@@ -24,9 +25,6 @@ private string Invoker()
}
#endif
-#if BUGFIX_TRIAL_20230611_001
- private static object marshal_lck = new object();
-#endif
internal readonly unsafe byte* ptr;
public unsafe KcpSegment(byte* intPtr, uint appendDateSize)
{
@@ -42,16 +40,9 @@ public unsafe KcpSegment(byte* intPtr, uint appendDateSize)
public static KcpSegment AllocHGlobal(int appendDateSize)
{
var total = LocalOffset + HeadOffset + appendDateSize;
-#if BUGFIX_TRIAL_20230611_001
- IntPtr intPtr;
- lock (marshal_lck)
- {
- intPtr = Marshal.AllocHGlobal(total);
- }
-#else
+
IntPtr intPtr = Marshal.AllocHGlobal(total);
-#endif
-#if KCP_PERFORMANCE_TEST
+#if false
Log.Verb($"KcpSegment memory alloc: 0x{intPtr:x}", nameof(KcpSegment));
#endif
unsafe
@@ -72,15 +63,8 @@ public static void FreeHGlobal(KcpSegment seg)
{
unsafe
{
-#if BUGFIX_TRIAL_20230611_001
- lock (marshal_lck)
- {
-#endif
- Marshal.FreeHGlobal((IntPtr)seg.ptr);
-#if BUGFIX_TRIAL_20230611_001
- }
-#endif
-#if KCP_PERFORMANCE_TEST
+ Marshal.FreeHGlobal((IntPtr)seg.ptr);
+#if false
Log.Verb($"KcpSegment memory free: 0x{(IntPtr)seg.ptr:x}", nameof(KcpSegment));
#endif
}
@@ -171,8 +155,36 @@ public uint xmit
}
}
+#if BYTE_CHECK_MODE
+
+ ///
+ /// offset = 16
+ ///
+ public uint byteCheckMode
+ {
+ get
+ {
+ unsafe
+ {
+ return *(uint*)(ptr + 16);
+ }
+ }
+ set
+ {
+ unsafe
+ {
+ *(uint*)(ptr + 16) = value;
+ }
+ }
+ }
+#endif
+
///以下为需要网络传输的参数
+#if BYTE_CHECK_MODE
+ public const int LocalOffset = 4 * 5;
+#else
public const int LocalOffset = 4 * 4;
+#endif
public const int HeadOffset = KcpConst.IKCP_OVERHEAD;
///
@@ -291,7 +303,7 @@ public byte frg
}
set
{
-#if KCP_PERFORMANCE_TEST
+#if false
Log.Verb($"Invoker: [{Invoker()}] assigned frg:{value} for KcpSegment: {this.ToLogString(false)}", nameof(KcpSegment));
#endif
unsafe
@@ -418,7 +430,7 @@ public uint sn
}
set
{
-#if KCP_PERFORMANCE_TEST
+#if false
Log.Verb($"Invoker: [{Invoker()}] assigned sn:{value} for KcpSegment: {this.ToLogString(false)}", nameof(KcpSegment));
#endif
unsafe
@@ -517,8 +529,52 @@ private set
}
}
+#if BYTE_CHECK_MODE
+ // miHoMo KCP modify: IUINT32 token
+ // Change line(s) in file compare: ikcp.h, +271
+#if !MIHOMO_KCP
+ ///
+ /// AppendDateSize
+ /// offset = + 24
+ ///
+#else
+ ///
+ /// offset = + 28
+ ///
+#endif
+ public uint byteCheckCode
+ {
+ get
+ {
+ unsafe
+ {
+ // miHoMo KCP modify: IUINT32 token
+ // Change line(s) in file compare: ikcp.h, +271
+#if !MIHOMO_KCP
+ return *(uint*)(LocalOffset + 24 + ptr);
+#else
+ return *(uint*)(LocalOffset + 28 + ptr);
+#endif
+ }
+ }
+ private set
+ {
+ unsafe
+ {
+ // miHoMo KCP modify: IUINT32 token
+ // Change line(s) in file compare: ikcp.h, +271
+#if !MIHOMO_KCP
+ *(uint*)(LocalOffset + 24 + ptr) = value;
+#else
+ *(uint*)(LocalOffset + 28 + ptr) = value;
+#endif
+ }
+ }
+ }
+#endif
+
///
- ///
+ ///
///
/// https://github.com/skywind3000/kcp/issues/35#issuecomment-263770736
public Span data
@@ -532,7 +588,25 @@ public Span data
}
}
-
+#if BYTE_CHECK_MODE
+ public void ComputeByteCheckCodeFromData()
+ {
+ switch (byteCheckMode)
+ {
+ case 1:
+ var buffer = data;
+ byteCheckCode = Crc32.HashToUInt32(buffer);
+ break;
+ case 2:
+ var buffer2 = data;
+ byteCheckCode = (uint)XxHash3.HashToUInt64(buffer2);
+ break;
+ default:
+ byteCheckCode = 0;
+ break;
+ }
+ }
+#endif
///
/// 将片段中的要发送的数据拷贝到指定缓冲区
@@ -542,6 +616,9 @@ public Span data
public int Encode(Span buffer)
{
var datelen = (int)(HeadOffset + len);
+#if BYTE_CHECK_MODE
+ if (byteCheckCode == 0) ComputeByteCheckCodeFromData();
+#endif
///备用偏移值 现阶段没有使用
const int offset = 0;
@@ -573,6 +650,9 @@ public int Encode(Span buffer)
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 12), sn);
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 16), una);
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 20), len);
+#if BYTE_CHECK_MODE
+ BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 24), byteCheckCode);
+#endif
#else
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset), conv);
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset), token);
@@ -584,6 +664,9 @@ public int Encode(Span buffer)
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 16), sn);
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 20), una);
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 24), len);
+#if BYTE_CHECK_MODE
+ BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 28), byteCheckCode);
+#endif
#endif
data.CopyTo(buffer.Slice(HeadOffset));
}
@@ -604,6 +687,9 @@ public int Encode(Span buffer)
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset + 12), sn);
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset + 16), una);
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset + 20), len);
+#if BYTE_CHECK_MODE
+ BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset + 24), byteCheckCode);
+#endif
#else
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset), conv);
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset), token);
@@ -615,6 +701,9 @@ public int Encode(Span buffer)
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset + 16), sn);
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset + 20), una);
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset + 24), len);
+#if BYTE_CHECK_MODE
+ BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset + 28), byteCheckCode);
+#endif
#endif
data.CopyTo(buffer.Slice(HeadOffset));
}
diff --git a/KCP/Kcp/SegManager.cs b/KCP/Kcp/SegManager.cs
index 278d21305..976dbf210 100644
--- a/KCP/Kcp/SegManager.cs
+++ b/KCP/Kcp/SegManager.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Buffers.Binary;
+using System.IO.Hashing;
namespace System.Net.Sockets.Kcp
{
@@ -216,10 +217,35 @@ public Seg(int blockSize)
public uint una { get; set; }
public ushort wnd { get; set; }
public uint xmit { get; set; }
+#if BYTE_CHECK_MODE
+ public uint byteCheckMode { get; set; }
+ public uint byteCheckCode { get; internal set; }
+
+ public void ComputeByteCheckCodeFromData()
+ {
+ switch (byteCheckMode)
+ {
+ case 1:
+ var buffer = data;
+ byteCheckCode = Crc32.HashToUInt32(buffer);
+ break;
+ case 2:
+ var buffer2 = data;
+ byteCheckCode = (uint)XxHash64.HashToUInt64(buffer2);
+ break;
+ default:
+ byteCheckCode = 0;
+ break;
+ }
+ }
+#endif
public int Encode(Span buffer)
{
var datelen = (int)(HeadOffset + len);
+#if BYTE_CHECK_MODE
+ if (byteCheckCode == 0) ComputeByteCheckCodeFromData();
+#endif
///备用偏移值 现阶段没有使用
const int offset = 0;
@@ -238,6 +264,9 @@ public int Encode(Span buffer)
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 12), sn);
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 16), una);
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 20), len);
+#if BYTE_CHECK_MODE
+ BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 24), byteCheckCode);
+#endif
#else
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset), conv);
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset), token);
@@ -249,6 +278,9 @@ public int Encode(Span buffer)
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 16), sn);
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 20), una);
BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 24), len);
+#if BYTE_CHECK_MODE
+ BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(offset + 28), byteCheckCode);
+#endif
#endif
data.CopyTo(buffer.Slice(HeadOffset));
}
@@ -266,6 +298,9 @@ public int Encode(Span buffer)
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset + 12), sn);
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset + 16), una);
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset + 20), len);
+#if BYTE_CHECK_MODE
+ BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset + 24), byteCheckCode);
+#endif
#else
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset), conv);
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset), token);
@@ -277,6 +312,9 @@ public int Encode(Span buffer)
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset + 16), sn);
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset + 20), una);
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset + 24), len);
+#if BYTE_CHECK_MODE
+ BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(offset + 28), byteCheckCode);
+#endif
#endif
data.CopyTo(buffer.Slice(HeadOffset));
@@ -307,6 +345,9 @@ public void Free(Seg seg)
{
seg.cmd = 0;
seg.conv = 0;
+#if MIHOMO_KCP
+ seg.token = 0;
+#endif
seg.fastack = 0;
seg.frg = 0;
seg.len = 0;
@@ -317,6 +358,10 @@ public void Free(Seg seg)
seg.una = 0;
seg.wnd = 0;
seg.xmit = 0;
+#if BYTE_CHECK_MODE
+ seg.byteCheckMode = 0;
+ seg.byteCheckCode = 0;
+#endif
Pool.Push(seg);
}
diff --git a/KCP/Kcp/SimpleKcpClient.cs b/KCP/Kcp/SimpleKcpClient.cs
index 7f6e889d4..0654c95c7 100644
--- a/KCP/Kcp/SimpleKcpClient.cs
+++ b/KCP/Kcp/SimpleKcpClient.cs
@@ -47,6 +47,7 @@ public void Output(IMemoryOwner buffer, int avalidLength, bool isKcpPacket
public async void SendAsync(byte[] datagram, int bytes)
{
kcp.Send(datagram.AsSpan().Slice(0, bytes));
+ await Task.CompletedTask;
}
public async ValueTask ReceiveAsync()
diff --git a/KCP/Kcp/Utility.cs b/KCP/Kcp/Utility.cs
index 64ac5084f..265322b41 100644
--- a/KCP/Kcp/Utility.cs
+++ b/KCP/Kcp/Utility.cs
@@ -50,7 +50,7 @@ public static uint ConvertTime(this in DateTimeOffset time)
public static string ToLogString(this T segment, bool local = false)
where T : IKcpSegment
{
-#if !KCP_PERFORMANCE_TEST
+#if true
if (local)
{
return $"sn:{segment.sn,2} una:{segment.una,2} frg:{segment.frg,2} cmd:{segment.cmd,2} len:{segment.len,2} wnd:{segment.wnd} [ LocalValue: xmit:{segment.xmit} fastack:{segment.fastack} rto:{segment.rto} ]";
diff --git a/NewProtoHandlers/NewProtoHandlers.csproj b/NewProtoHandlers/NewProtoHandlers.csproj
index a6d14ff79..dd88f3c97 100644
--- a/NewProtoHandlers/NewProtoHandlers.csproj
+++ b/NewProtoHandlers/NewProtoHandlers.csproj
@@ -19,7 +19,7 @@
-
+
diff --git a/OldProtoHandlers/OldProtoHandlers.csproj b/OldProtoHandlers/OldProtoHandlers.csproj
index 75e9a96e7..847c7eb6f 100644
--- a/OldProtoHandlers/OldProtoHandlers.csproj
+++ b/OldProtoHandlers/OldProtoHandlers.csproj
@@ -19,7 +19,7 @@
-
+
diff --git a/ProtoshiftHandlers/ProtoshiftHandlers.csproj b/ProtoshiftHandlers/ProtoshiftHandlers.csproj
index 1483d808d..36f6e37f7 100644
--- a/ProtoshiftHandlers/ProtoshiftHandlers.csproj
+++ b/ProtoshiftHandlers/ProtoshiftHandlers.csproj
@@ -27,7 +27,7 @@
-
+
diff --git a/Tests/KcpTests/KcpPerformanceTest/Analysis/MainAnalysis.cs b/Tests/KcpTests/KcpPerformanceTest/Analysis/MainAnalysis.cs
index 2b49c4539..f7e676395 100644
--- a/Tests/KcpTests/KcpPerformanceTest/Analysis/MainAnalysis.cs
+++ b/Tests/KcpTests/KcpPerformanceTest/Analysis/MainAnalysis.cs
@@ -10,6 +10,7 @@ namespace csharp_Protoshift.MhyKCP.Test.Analysis
internal static class MainAnalysis
{
public static bool TestsFinished { get; private set; } = false;
+ public static int ProgramExitCode { get; private set; } = 0;
///
/// 客户端发出全部包后调用,在10s后锁定,并停止Proxy与Server的数据收集并创建副本
@@ -52,6 +53,7 @@ public static async Task ClientFinished()
TestsFinished = true;
}
+#pragma warning disable CS0168
static ReadOnlyBasePacketRecord[]?
client_sent, client_recved,
#if CONNECT_SERVERONLY
@@ -61,6 +63,7 @@ static ReadOnlyBasePacketRecord[]?
server_recved, server_sent,
proxy_server_recved, proxy_server_sent;
#endif
+#pragma warning restore CS0168
private static async Task HandleData()
{
@@ -204,6 +207,8 @@ private static async Task HandleData()
acklist += $"{loss}; ";
}
acklist += "]";
+ if (Cs_proxy_failed.lost_ack.Any())
+ ProgramExitCode = 114514;
Output(stringRes, acklist);
#endregion
Output(stringRes);
@@ -216,6 +221,8 @@ private static async Task HandleData()
acklist += $"{loss}; ";
}
acklist += "]";
+ if (Sc_proxy_failed.lost_ack.Any())
+ ProgramExitCode = 114514;
Output(stringRes, acklist);
#endregion
Output(stringRes);
@@ -333,6 +340,7 @@ private static void OutputLossAck(StringBuilder target, PacketLossResult lossRes
}
else
{
+ ProgramExitCode = 114514;
Output(target, $"{from_friendlyName} -> {to_friendlyName} 丢包情况:");
Output(target, $" 出现了 {lossResult.lost_ack.Length} 个包丢失。ack 列表:");
#region Lost packet
@@ -365,6 +373,7 @@ private static void OutputInvertedPacket(StringBuilder target, PacketDelayResult
{
if (delay.inverted_ack_list.Length != 0)
{
+ ProgramExitCode = 114514;
Output(target, $"{from_friendlyName} -> {to_friendlyName}: 出现了 {delay.inverted_ack_list.Length} 次乱序现象。");
foreach (var inverted_pkt in delay.inverted_ack_list)
{
diff --git a/Tests/KcpTests/KcpPerformanceTest/Client/ClientApp.cs b/Tests/KcpTests/KcpPerformanceTest/Client/ClientApp.cs
index 67527c02b..53a1c85ca 100644
--- a/Tests/KcpTests/KcpPerformanceTest/Client/ClientApp.cs
+++ b/Tests/KcpTests/KcpPerformanceTest/Client/ClientApp.cs
@@ -21,9 +21,9 @@ public ClientApp(uint clientId)
public async Task Start()
{
#if CONNECT_SERVERONLY
- KCPClient kcpClient = new(new(IPAddress.Loopback, Constants.UDP_SERVER_PORT));
+ KCPClient kcpClient = new(new IPEndPoint(IPAddress.Loopback, Constants.UDP_SERVER_PORT));
#else
- KCPClient kcpClient = new(new(IPAddress.Loopback, Constants.UDP_PROXY_PORT));
+ KCPClient kcpClient = new(new IPEndPoint(IPAddress.Loopback, Constants.UDP_PROXY_PORT));
#endif
await kcpClient.ConnectAsync();
#if CONNECT_SERVERONLY
@@ -31,7 +31,7 @@ public async Task Start()
#else
Log.Info($"KCPClient connected to localhost:{Constants.UDP_PROXY_PORT}.", nameof(ClientApp));
#endif
- _ = Task.Run(async () =>
+ Util.RunBackground(async () =>
{
int sum_wait_ms = 0;
uint ack = (uint)(Constants.packet_repeat_time * 2 * clientId + 1);
@@ -52,7 +52,7 @@ public async Task Start()
{
BasePacket pkt = BasePacket.Generate(ack, (uint)Constants.each_packet_size);
kcpClient.Send(pkt.GetBytes());
- Log.Verb($"Client sent ack: {ack}", "ClientSender");
+ Log.Verb($"Client sent ack: {ack} (id: {pkt.Unique_ID})", "ClientSender");
ClientDataChannel.PushSentPacket(pkt);
pkt.Dispose();
sum_wait_ms += Constants.packet_interval_ms;
@@ -70,9 +70,9 @@ public async Task Start()
ack += 2;
}
_finished = true;
- });
+ }, $"The sender of Client {clientId} has met a fatal error. ", "ClientSender");
- _ = Task.Run(() =>
+ Util.RunBackground(() =>
{
while (true)
{
@@ -81,7 +81,7 @@ public async Task Start()
var data = kcpClient.Receive();
var packet = new BasePacket(data);
ClientDataChannel.PushReceivedPacket(packet);
- Log.Verb($"Client recved packet: isStructureValid:{packet.isStructureValid}, isBodyValid:{packet.isBodyValid}, ack:{packet.ack}, bodyLen:{packet.bodyLen}");
+ Log.Verb($"Client recved packet: isStructureValid:{packet.isStructureValid}, isBodyValid:{packet.isBodyValid}, ack:{packet.ack}, id:{packet.Unique_ID}, bodyLen:{packet.bodyLen}", "ClientReceiver");
packet.Dispose();
}
catch (Exception ex)
@@ -89,7 +89,7 @@ public async Task Start()
Log.Erro($"Client receiving packet meets exception: {ex}", "ClientReceiver_AsyncTask");
}
}
- });
+ }, $"The receiver of Client {clientId} has met a fatal error. ", "ClientReceiver");
}
internal static async Task WaitForAllClients()
diff --git a/Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj b/Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
index faaca28bd..e96732dfa 100644
--- a/Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
+++ b/Tests/KcpTests/KcpPerformanceTest/KcpPerformanceTest.csproj
@@ -9,19 +9,19 @@
-
- $(DefineConstants)
+
+ $(DefineConstants);DISABLED_BYTE_CHECK_MODE
-
- $(DefineConstants)
+
+ $(DefineConstants);DISABLED_BYTE_CHECK_MODE
-
+
diff --git a/Tests/KcpTests/KcpPerformanceTest/Program.cs b/Tests/KcpTests/KcpPerformanceTest/Program.cs
index 09223fdb5..7f93071da 100644
--- a/Tests/KcpTests/KcpPerformanceTest/Program.cs
+++ b/Tests/KcpTests/KcpPerformanceTest/Program.cs
@@ -1,5 +1,6 @@
using CommandLine;
using CommandLine.Text;
+using csharp_Protoshift.MhyKCP.Test;
using csharp_Protoshift.MhyKCP.Test.Analysis;
using csharp_Protoshift.MhyKCP.Test.App;
using csharp_Protoshift.resLoader;
@@ -15,13 +16,8 @@ private static async Task Main(string[] args)
max_Output_Char_Count: 16 * 1024,
use_Console_Wrapper: false,
use_Working_Directory: true,
-#if DEBUG
global_Minimum_LogLevel: LogLevel.Verbose,
console_Minimum_LogLevel: LogLevel.Information,
-#else
- global_Minimum_LogLevel: LogLevel.Information,
- console_Minimum_LogLevel: LogLevel.Information,
-#endif
debug_LogWriter_AutoFlush: true
));
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
@@ -45,7 +41,7 @@ private static async Task Main(string[] args)
Environment.Exit(1);
});
- await ServerApp.Start();
+ ServerApp.Start();
#if !CONNECT_SERVERONLY
ProxyApp.Start();
#endif
@@ -60,13 +56,13 @@ private static async Task Main(string[] args)
while (true)
{
if (!MainAnalysis.TestsFinished) await Task.Delay(10000);
- else Environment.Exit(0);
+ else Environment.Exit(MainAnalysis.ProgramExitCode);
}
}
else
{
Console.ReadLine();
- Environment.Exit(0);
+ Environment.Exit(MainAnalysis.ProgramExitCode);
}
}
diff --git a/Tests/KcpTests/KcpPerformanceTest/Protocol/Mihomonet.cs b/Tests/KcpTests/KcpPerformanceTest/Protocol/Mihomonet.cs
index d8ff8b418..2123fa947 100644
--- a/Tests/KcpTests/KcpPerformanceTest/Protocol/Mihomonet.cs
+++ b/Tests/KcpTests/KcpPerformanceTest/Protocol/Mihomonet.cs
@@ -72,7 +72,9 @@ private void InitBuffer(int length, string? invoker_log = null)
}
#region 发送端 造包相关代码
+#pragma warning disable CS8618 // InitBuffer
private BasePacket(int length)
+#pragma warning restore CS8618
{
lock (increasing_id_lock) Unique_ID = increasing_id++;
InitBuffer(length, $"{nameof(BasePacket)}({Unique_ID})_Ctor(len)");
@@ -134,7 +136,9 @@ public BasePacket(byte[]? packet)
return;
}
InitBuffer(packet.Length, $"{nameof(BasePacket)}({Unique_ID})_Ctor(arr)");
+#pragma warning disable CS8604 // InitBuffer
Buffer.BlockCopy(packet, 0, _baseBuffer, 0, packet.Length);
+#pragma warning restore CS8604
XorDecrypt(ref _baseBuffer);
#if DEBUG
Log.Verb($"Created BasePacket from array (decrypted): {Convert.ToHexString(_baseBuffer, 0, Math.Min(_baseBuffer.Length, (int)CalculateLength((uint)Constants.each_packet_size)))}", $"{nameof(BasePacket)}({Unique_ID})_Ctor(arr)");
diff --git a/Tests/KcpTests/KcpPerformanceTest/Proxy/GameSession/GameSessionDispatch.cs b/Tests/KcpTests/KcpPerformanceTest/Proxy/GameSession/GameSessionDispatch.cs
index f2e83387d..87fdec2cb 100644
--- a/Tests/KcpTests/KcpPerformanceTest/Proxy/GameSession/GameSessionDispatch.cs
+++ b/Tests/KcpTests/KcpPerformanceTest/Proxy/GameSession/GameSessionDispatch.cs
@@ -96,28 +96,30 @@ public static bool ClientPacketOrdered(byte[] data, uint conv)
#endregion
#region Packet Record Saver
- public static async Task DestroySession(uint conv)
+ private static object clearup_running_lck = "miHomo Save The World";
+ public static void DestroySession(uint conv)
{
- if (!sessions.ContainsKey(conv)) return;
- sessions.TryRemove(conv, out HandlerSession? session);
- cancelledSessions.Add(conv);
-
- if (session == null)
+ lock (clearup_running_lck)
{
- Log.Erro($"Session {conv} destroyed but null, probably not recorded!", "GameSessionDispatch");
- return;
+ if (!sessions.ContainsKey(conv)) return;
+ sessions.TryRemove(conv, out HandlerSession? session);
+ cancelledSessions.Add(conv);
+
+ if (session == null)
+ {
+ Log.Erro($"Session {conv} destroyed but null, probably not recorded!", "GameSessionDispatch");
+ return;
+ }
}
}
public static void CloseServer()
{
Closed = true;
- List tasks = new();
foreach (var conv in sessions.Keys)
{
- tasks.Add(DestroySession(conv));
+ DestroySession(conv);
}
- Task.WaitAll(tasks.ToArray());
}
#endregion
diff --git a/Tests/KcpTests/KcpPerformanceTest/Proxy/GameSession/HandlerSession.cs b/Tests/KcpTests/KcpPerformanceTest/Proxy/GameSession/HandlerSession.cs
index 4e3f0f7fc..5d2d7cf12 100644
--- a/Tests/KcpTests/KcpPerformanceTest/Proxy/GameSession/HandlerSession.cs
+++ b/Tests/KcpTests/KcpPerformanceTest/Proxy/GameSession/HandlerSession.cs
@@ -70,34 +70,6 @@ public byte[] HandlePacket(byte[] packet, bool isNewCmdid)
public bool PacketOrdered(byte[] packet, bool isNewCmdid)
{
- /* Due to current researches, after the urgent packet split was added,
- * nothing about network but the Ping value shown in the game has improved,
- * and the worst thing is that Protoshift became no longer stable,
- * including the same bug as YuFanXing/Protoshift randomly appear at 60% of time.
- * That's unbearable but exchanged not much efficiency increase,
- * as the base KCP implement is synchronous -- by bussy locks.
- * It makes UrgentPacket implement nearly unnecessary at all
- * -- as nearly most of packets are sent syncronous actually.
- * But the disadvantages are preserved. Some important packets are sent asyncronously,
- * but because UdpClient isn't thread-safe, they are possibly dropped or cracked.
- * So, considered all the factors, I decided to give up the UrgentPacket implement.
- *
- * For actual performance improve solutions, some of following ways should be considered:
- * - KcpProxy sub clients.
- * Though the KcpProxy and KCPServer are designed for multiple clients,
- * the KCP base and UdpClient base aren't. Therefore, the most ideal conditions are that
- * there's one KcpServer instance for each client.
- * - Approach the Java Protoshift implement.
- * The most important Protoshift means in this project is deserialize the message
- * from one protocol to a general inner json content, and serialize it to another protocol.
- * Compared to this, YuFanXing/Protoshift directly transfers variables from protocols
- * by generated codes, so it was surely more efficient.
- * According to tests, handling a 224KB PlayerLoginRsp packet costs (in HandlerSession only)
- * about 68ms in total.
- * - Change the base UDP and KCP implements.
- * The reason has been mentioned repeatedly above, but notice that
- * it works only when UDP and KCP implements are both thread-safe.
- */
// return true;
if (packet == null) throw new ArgumentNullException(nameof(packet));
XorDecrypt(ref packet, 0, 2);
diff --git a/Tests/KcpTests/KcpPerformanceTest/Proxy/ProxyApp.cs b/Tests/KcpTests/KcpPerformanceTest/Proxy/ProxyApp.cs
index 28f33d5aa..21bf8ba1c 100644
--- a/Tests/KcpTests/KcpPerformanceTest/Proxy/ProxyApp.cs
+++ b/Tests/KcpTests/KcpPerformanceTest/Proxy/ProxyApp.cs
@@ -12,8 +12,8 @@ public static void Start()
#if CONNECT_SERVERONLY
throw new NotImplementedException("Proxy should not be launched in CONNECT_SERVERONLY mode.");
#else
- KcpProxyServer proxy = new(new(IPAddress.Loopback, Constants.UDP_PROXY_PORT),
- new(IPAddress.Loopback, Constants.UDP_SERVER_PORT));
+ KcpProxyServer proxy = new(new IPEndPoint(IPAddress.Loopback, Constants.UDP_PROXY_PORT),
+ new IPEndPoint(IPAddress.Loopback, Constants.UDP_SERVER_PORT));
ProxyHandlers handlers = new ProxyHandlers
{
OnServerPacketArrival = GameSessionDispatch.HandleServerPacket,
@@ -21,7 +21,7 @@ public static void Start()
ServerPacketOrdered = GameSessionDispatch.ServerPacketOrdered,
ClientPacketOrdered = GameSessionDispatch.ClientPacketOrdered
};
- _ = Task.Run(() => proxy.StartProxy(handlers));
+ Util.RunBackground(() => proxy.StartProxy(handlers), "ProxyApp has met a fatal error. ", nameof(ProxyApp));
Log.Info($"KcpProxyServer started on 127.0.0.1:{Constants.UDP_PROXY_PORT}", nameof(ProxyApp));
#endif
}
diff --git a/Tests/KcpTests/KcpPerformanceTest/Server/ServerApp.cs b/Tests/KcpTests/KcpPerformanceTest/Server/ServerApp.cs
index 43f373ac5..440868664 100644
--- a/Tests/KcpTests/KcpPerformanceTest/Server/ServerApp.cs
+++ b/Tests/KcpTests/KcpPerformanceTest/Server/ServerApp.cs
@@ -7,12 +7,12 @@ namespace csharp_Protoshift.MhyKCP.Test.App
{
public static class ServerApp
{
- public static async Task Start()
+ public static void Start()
{
- KCPServer kcpServer = new(new(IPAddress.Loopback, Constants.UDP_SERVER_PORT));
+ KCPServer kcpServer = new(new IPEndPoint(IPAddress.Loopback, Constants.UDP_SERVER_PORT));
Log.Info($"KCPServer listening on localhost:{Constants.UDP_SERVER_PORT}.", nameof(ServerApp));
- _ = Task.Run(() =>
+ Util.RunBackground(() =>
{
while (true)
{
@@ -20,7 +20,7 @@ public static async Task Start()
Log.Info($"New connection from {accepted.RemoteEndpoint}.", "ServerListening_AsyncTask");
var conn = accepted.Connection;
// TODO: Push state to analysis
- _ = Task.Run(() =>
+ Util.RunBackground(() =>
{
while (true)
{
@@ -47,7 +47,7 @@ public static async Task Start()
continue;
}
ServerDataChannel.PushReceivedPacket(pkt);
- Log.Verb($"Server received packet: length:{data?.Length}, isStructureValid:{pkt.isStructureValid}, isBodyValid:{pkt.isBodyValid}, ack:{pkt.ack}, bodyLen:{pkt.bodyLen}", "ServerReceiver");
+ Log.Verb($"Server received packet: length:{data?.Length}, isStructureValid:{pkt.isStructureValid}, isBodyValid:{pkt.isBodyValid}, ack:{pkt.ack}, id:{pkt.Unique_ID}, bodyLen:{pkt.bodyLen}", "ServerReceiver");
if (pkt.isStructureValid)
{
try
@@ -63,10 +63,15 @@ public static async Task Start()
continue;
}
}
+ else
+ {
+ Log.Warn($"致命错误:服务端收到包(ID:{pkt.Unique_ID})结构错误。", "BasePacket");
+ Log.Warn($"BasePacket ID:{pkt.Unique_ID}'s Hexdump: {Convert.ToHexString(data ?? Array.Empty())}");
+ }
}
- });
+ }, $"The receiver of packet from {accepted.RemoteEndpoint} has met a fatal error.", nameof(ServerApp));
}
- });
+ }, "ServerApp (Accept) has met a fatal error.", nameof(ServerApp));
}
}
}
\ No newline at end of file
diff --git a/Tests/KcpTests/KcpPerformanceTest/Util.cs b/Tests/KcpTests/KcpPerformanceTest/Util.cs
index bc7467ee8..41a6f0b89 100644
--- a/Tests/KcpTests/KcpPerformanceTest/Util.cs
+++ b/Tests/KcpTests/KcpPerformanceTest/Util.cs
@@ -1,4 +1,5 @@
using System.Diagnostics;
+using YYHEggEgg.Logger;
namespace csharp_Protoshift.MhyKCP.Test
{
@@ -41,7 +42,41 @@ public static string GetInvoker()
{
StackTrace stackTrace = new StackTrace();
StackFrame? frame = stackTrace.GetFrame(2);
- return frame.ToString();
+ return frame?.ToString() ?? "";
+ }
+
+ ///
+ /// 创建一个任务,将指定委托置于后台运行。
+ ///
+ /// 要运行的无参委托。
+ /// 当委托出现未处理的异常时,传递给 信息的一部分。一般是一个完整的句子,其后接异常信息。
+ /// 当委托出现未处理的异常时,传递给 信息的日志 sender。
+ public static void RunBackground(Action action, string fatal_notice, string log_sender = $"{nameof(Util)}_{nameof(RunBackground)}")
+ {
+ _ = Task.Run(action).ContinueWith(t =>
+ {
+ if (t.IsFaulted)
+ {
+ Log.Erro($"{fatal_notice} {t.Exception}", log_sender);
+ }
+ }, TaskContinuationOptions.OnlyOnFaulted);
+ }
+
+ ///
+ /// 创建一个任务,将指定委托置于后台运行。
+ ///
+ /// 要运行的无参委托。
+ /// 当委托出现未处理的异常时,传递给 信息的一部分。一般是一个完整的句子,其后接异常信息。
+ /// 当委托出现未处理的异常时,传递给 信息的日志 sender。
+ public static void RunBackground(Func action, string fatal_notice, string log_sender = $"{nameof(Util)}_{nameof(RunBackground)}")
+ {
+ _ = Task.Run(action).ContinueWith(t =>
+ {
+ if (t.IsFaulted)
+ {
+ Log.Erro($"{fatal_notice} {t.Exception}", log_sender);
+ }
+ }, TaskContinuationOptions.OnlyOnFaulted);
}
///
@@ -61,7 +96,7 @@ public static string AddNumberedSuffixToPath(string filePath)
*/
if (File.Exists(filePath))
{
- string directory = Path.GetDirectoryName(filePath);
+ string directory = Path.GetDirectoryName(filePath) ?? string.Empty;
string fileName = Path.GetFileNameWithoutExtension(filePath);
string extension = Path.GetExtension(filePath);
string newFilePath = filePath;
@@ -77,7 +112,7 @@ public static string AddNumberedSuffixToPath(string filePath)
}
else if (Directory.Exists(filePath))
{
- string directoryName = Path.GetDirectoryName(filePath);
+ string directoryName = Path.GetDirectoryName(filePath) ?? string.Empty;
string directory = Path.Combine(directoryName, Path.GetFileName(filePath));
string newDirectory = directory;
int suffix = 1;
diff --git a/Tests/KcpTests/SharedLib/KCP/KcpProxy/KcpProxyBase.cs b/Tests/KcpTests/SharedLib/KCP/KcpProxy/KcpProxyBase.cs
index 1ff46c7b0..6f5d312ce 100644
--- a/Tests/KcpTests/SharedLib/KCP/KcpProxy/KcpProxyBase.cs
+++ b/Tests/KcpTests/SharedLib/KCP/KcpProxy/KcpProxyBase.cs
@@ -1,5 +1,6 @@
-// #define KCP_PROXY_VERBOSE
+// #define KCP_PROXY_VERBOSE
+using Newtonsoft.Json.Linq;
using System.Net;
using System.Net.Sockets;
using YSFreedom.Common.Util;
@@ -13,11 +14,12 @@ namespace csharp_Protoshift.MhyKCP.Proxy
public class KcpProxyBase : MhyKcpBase
{
public KcpProxyClient? sendClient;
- public IPEndPoint sendToAddress;
+ public EndPoint sendToAddress;
+ protected static LoggerChannel? _kcpstatlogchan = KcpProxyServer._kcpstatlogger?.GetChannel(null);
private object handshake_lock = "Tighnari beloved";
- public KcpProxyBase(IPEndPoint sendToAddress, uint conv = 0, uint token = 0,
+ public KcpProxyBase(EndPoint sendToAddress, uint conv = 0, uint token = 0,
Func? PacketHandler = null)
: base(conv, token)
{
@@ -62,6 +64,7 @@ private int InnerInput(byte[] buffer)
disconn.Decode(buffer, Handshake.MAGIC_DISCONNECT);
_State = ConnectionState.CLOSED;
Log.Info($"Client (conv: {_Conv}) requested disconnect (reason: {disconn.Data}), so send disconnect to server", nameof(KcpProxyBase));
+ _kcpstatlogchan?.LogInfo($"0|kcp|disconnect|from_client|token={disconn.Token}|reason={disconn.Data}");
sendClient?.Disconnect(disconn.Conv, disconn.Token, disconn.Data);
return 0;
@@ -70,7 +73,7 @@ private int InnerInput(byte[] buffer)
{
// Reconnect
disconn.Decode(buffer, Handshake.MAGIC_CONNECT);
- Log.Info("Client requested reconnect, set to WAIT", nameof(KcpProxyBase));
+ Log.Dbug("Client requested reconnect, set to WAIT", nameof(KcpProxyBase));
goto case ConnectionState.HANDSHAKE_WAIT;
}
@@ -109,14 +112,18 @@ private int InnerInput(byte[] buffer)
// Debug.Assert(sendClient == null);
sendClient = new(sendToAddress, handshake.Conv, handshake.Token, handshake.Data);
- sendClient.ConnectAsync().Wait();
+ sendClient.ConnectAsync().Wait();
+
+ var sendBackConv = sendClient.GetSendbackHandshake();
+ if (_kcpstatlogchan != null)
+ _kcpstatlogchan.LogSender = sendBackConv.Conv.ToString();
sendClient.StartDisconnected += (conv, token, data) =>
{
- Log.Warn($"Server (conv: {_Conv}) requested to disconnect (reason: {data}), so send disconnect to client", nameof(KcpProxyBase));
+ Log.Info($"Server (conv: {_Conv}) requested to disconnect (reason: {data}), so send disconnect to client", nameof(KcpProxyBase));
+ _kcpstatlogchan?.LogInfo($"0|kcp|disconnect|from_server|token={token}|reason={data}");
Disconnect(conv, token, data);
};
-
- var sendBackConv = sendClient.GetSendbackHandshake();
+
var sendBackData = sendBackConv.AsBytes();
OutputCallback?.Output(new KcpInnerBuffer(sendBackData), sendBackData.Length, false);
_Conv = sendBackConv.Conv;
@@ -133,7 +140,7 @@ private int InnerInput(byte[] buffer)
}
case ConnectionState.HANDSHAKE_CONNECT:
{
- Log.Erro("KcpProxy is not a client but reached HANDSHAKE_CONNECT", nameof(KcpProxyBase));
+ Log.Dbug("KcpProxy is not a client but reached HANDSHAKE_CONNECT", nameof(KcpProxyBase));
break;
/*var handshake = new Handshake();
try
diff --git a/Tests/KcpTests/SharedLib/KCP/KcpProxy/KcpProxyClient.cs b/Tests/KcpTests/SharedLib/KCP/KcpProxy/KcpProxyClient.cs
index d114c39f8..140cbbbbe 100644
--- a/Tests/KcpTests/SharedLib/KCP/KcpProxy/KcpProxyClient.cs
+++ b/Tests/KcpTests/SharedLib/KCP/KcpProxy/KcpProxyClient.cs
@@ -1,11 +1,11 @@
-using System.Diagnostics;
+using System.Diagnostics;
using System.Net;
namespace csharp_Protoshift.MhyKCP.Proxy
{
public class KcpProxyClient : KCPClient
{
- public KcpProxyClient(IPEndPoint ipEp, uint conv = 0, uint token = 0, uint connectData = 0x499602D2)
+ public KcpProxyClient(EndPoint ipEp, uint conv = 0, uint token = 0, uint connectData = 0x499602D2)
: base(ipEp)
{
server = new(conv, token, connectData);
diff --git a/Tests/KcpTests/SharedLib/KCP/KcpProxy/KcpProxyServer.cs b/Tests/KcpTests/SharedLib/KCP/KcpProxy/KcpProxyServer.cs
index 1f07b520e..6fa3846ca 100644
--- a/Tests/KcpTests/SharedLib/KCP/KcpProxy/KcpProxyServer.cs
+++ b/Tests/KcpTests/SharedLib/KCP/KcpProxy/KcpProxyServer.cs
@@ -1,4 +1,4 @@
-// #define KCP_PROXY_VERBOSE // not avaliable currently
+// #define KCP_PROXY_VERBOSE // not avaliable currently
using System.Net;
using YYHEggEgg.Logger;
@@ -10,9 +10,43 @@ namespace csharp_Protoshift.MhyKCP.Proxy
{
public class KcpProxyServer : KCPServer
{
- public IPEndPoint SendToEndpoint { get; }
+ public EndPoint SendToEndpoint { get; }
+ internal static BaseLogger? _kcpstatlogger;
- public KcpProxyServer(IPEndPoint bindToAddress, IPEndPoint sendToAddress)
+#if !PROTOSHIFT_BENCHMARK
+ static KcpProxyServer()
+ {
+#if !KCP_PERFORMANCE_TEST
+ if (BaseLogger.LogFileExists("player.stat"))
+ {
+#endif
+ var customconf = Log.GlobalConfig;
+#if DEBUG
+ customconf.Global_Minimum_LogLevel = LogLevel.Debug;
+#else
+ customconf.Global_Minimum_LogLevel = LogLevel.Information;
+#endif
+ customconf.Console_Minimum_LogLevel = LogLevel.None;
+ _kcpstatlogger = new BaseLogger(customconf, new LogFileConfig
+ {
+ AutoFlushWriter = true,
+ IsPipeSeparatedFile = true,
+ MaximumLogLevel = LogLevel.Error,
+#if DEBUG
+ MinimumLogLevel = LogLevel.Debug,
+#else
+ MinimumLogLevel = LogLevel.Information,
+#endif
+ FileIdentifier = "player.stat",
+ AllowAutoFallback = true,
+ });
+#if !KCP_PERFORMANCE_TEST
+ }
+#endif
+ }
+#endif
+
+ public KcpProxyServer(IPEndPoint bindToAddress, EndPoint sendToAddress)
{
udpSock = new SocketUdpClient(bindToAddress, true);
SendToEndpoint = sendToAddress;
@@ -33,7 +67,7 @@ protected override async Task BackgroundUpdate()
}
catch (Exception ex)
{
- Log.Dbug($"BackgroundUpdate receiving packet meets error and restart: {ex}", nameof(KcpProxyServer));
+ LogTrace.DbugTrace(ex, nameof(KcpProxyServer), $"BackgroundUpdate receiving packet meets error and restart. ");
continue;
}
if (packet.Buffer.Length == Handshake.LEN)
@@ -52,7 +86,8 @@ protected override async Task BackgroundUpdate()
}
catch (Exception ex)
{
- Log.Dbug($"BackgroundUpdate:Connected reached exception {ex}", nameof(KcpProxyServer));
+ LogTrace.DbugTrace(ex, nameof(KcpProxyServer),
+ $"BackgroundUpdate:Connected reached exception. ");
if (connected_conn.State != MhyKcpBase.ConnectionState.CONNECTED)
{
connected_clients.TryRemove(connected_conn.Conv, out _);
@@ -68,9 +103,8 @@ protected override async Task BackgroundUpdate()
continue;
}
// ip dispatch
- string remoteIpString = packet.RemoteEndPoint.ToString();
KcpProxyBase conn;
- if (!connecting_clients.TryGetValue(remoteIpString, out var _outconn))
+ if (!connecting_clients.TryGetValue(packet.RemoteEndPoint, out var _outconn))
{
// Don't allow a disconnected session
if (removed_sessions.Contains(handshake.Conv))
@@ -81,9 +115,9 @@ protected override async Task BackgroundUpdate()
// Oh boy! A new connection!
conn = new KcpProxyBase(sendToAddress: SendToEndpoint);
conn.OutputCallback = new SocketUdpKcpCallback(udpSock, packet.RemoteEndPoint);
- Log.Dbug($"New connection established, remote endpoint={remoteIpString}");
+ Log.Dbug($"New connection established, remote endpoint={packet.RemoteEndPoint}", nameof(KcpProxyServer));
conn.AcceptNonblock();
- connecting_clients[remoteIpString] = conn;
+ connecting_clients[packet.RemoteEndPoint] = conn;
_ = Task.Run(async () =>
{
try
@@ -92,7 +126,7 @@ protected override async Task BackgroundUpdate()
}
catch
{
- connecting_clients.TryRemove(remoteIpString, out _);
+ connecting_clients.TryRemove(packet.RemoteEndPoint, out _);
}
});
}
@@ -107,7 +141,8 @@ protected override async Task BackgroundUpdate()
}
catch (Exception ex)
{
- Log.Dbug($"BackgroundUpdate:NewConnection reached exception {ex}", nameof(KcpProxyServer));
+ LogTrace.DbugTrace(ex, nameof(KcpProxyServer),
+ $"BackgroundUpdate:NewConnection reached exception. ");
}
}
else if (packet.Buffer.Length >= KcpConst.IKCP_OVERHEAD) // conv dispatch
@@ -142,6 +177,7 @@ public void StartProxy(ProxyHandlers handlers)
{
var ret = Accept();
Log.Info($"New connection (conv={ret.Connection.Conv}, token={ret.Connection.Token}) from {ret.RemoteEndpoint}.", nameof(KcpProxyServer));
+ _kcpstatlogger?.Info($"0|kcp|connect|token={ret.Connection.Token}|ip={ret.RemoteEndpoint}", ret.Connection.Conv.ToString());
handlers.SessionCreated?.Invoke(ret.Connection.Conv, ret.RemoteEndpoint);
_ = Task.Run(() => HandleServer((KcpProxyBase)ret.Connection, handlers));
@@ -149,7 +185,7 @@ public void StartProxy(ProxyHandlers handlers)
}
catch (Exception ex)
{
- Log.Erro($"Internal error: {ex}", nameof(StartProxy));
+ LogTrace.ErroTrace(ex, nameof(StartProxy), $"Internal error. ");
}
}
}
@@ -298,6 +334,28 @@ public void SendPacketToServer(uint conv, byte[] content)
conn.sendClient.Send(content);
#pragma warning restore CS8602 // 解引用可能出现空引用。
}
+
+ ///
+ /// Kick a specified session and send disconnect packet to client & server.
+ ///
+ ///
+ /// The disconnect reason that will be sent to client. Default is ENET_SERVER_KICK (The connection to the server has been lost).
+ /// The disconnect reason that will be sent to server. Default is ENET_CLIENT_CLOSE.
+ ///
+ public void KickSession(uint conv, uint client_reason = 5, uint server_reason = 1)
+ {
+ if (!connected_clients.ContainsKey(conv))
+ {
+ throw new KeyNotFoundException($"The specified session (conv: {conv}) does not exist.");
+ }
+ var conn_client = (KcpProxyBase)connected_clients[conv];
+ var conn_server = conn_client.sendClient;
+
+ _kcpstatlogger?.Info($"0|kcp|disconnect|proxy_kick(client)|reason={client_reason}", conv.ToString());
+ _kcpstatlogger?.Info($"0|kcp|disconnect|proxy_kick(server)|reason={server_reason}", conv.ToString());
+ conn_client.Disconnect(data: client_reason);
+ conn_server?.Disconnect(data: server_reason);
+ }
#endregion
}
}
diff --git a/Tests/KcpTests/SharedLib/KCP/KcpProxy/ProxyHandlers.cs b/Tests/KcpTests/SharedLib/KCP/KcpProxy/ProxyHandlers.cs
index 42a82ebb2..91f274b63 100644
--- a/Tests/KcpTests/SharedLib/KCP/KcpProxy/ProxyHandlers.cs
+++ b/Tests/KcpTests/SharedLib/KCP/KcpProxy/ProxyHandlers.cs
@@ -1,18 +1,18 @@
-using System.Net;
-
-namespace csharp_Protoshift.MhyKCP.Proxy
-{
- public class ProxyHandlers
- {
- public Action? SessionCreated;
- public Action? SessionDestroyed;
- public Func OnServerPacketArrival
- = (data, conv) => data;
- public Func OnClientPacketArrival
- = (data, conv) => data;
- public Func ServerPacketOrdered
- = (_, _) => true;
- public Func ClientPacketOrdered
- = (_, _) => true;
- }
+using System.Net;
+
+namespace csharp_Protoshift.MhyKCP.Proxy
+{
+ public class ProxyHandlers
+ {
+ public Action? SessionCreated;
+ public Action? SessionDestroyed;
+ public Func OnServerPacketArrival
+ = (data, conv) => data;
+ public Func OnClientPacketArrival
+ = (data, conv) => data;
+ public Func ServerPacketOrdered
+ = (_, _) => true;
+ public Func ClientPacketOrdered
+ = (_, _) => true;
+ }
}
\ No newline at end of file
diff --git a/Tests/KcpTests/SharedLib/KCP/MhyKCP/KCPClient.cs b/Tests/KcpTests/SharedLib/KCP/MhyKCP/KCPClient.cs
index 77065effd..49e477f6d 100644
--- a/Tests/KcpTests/SharedLib/KCP/MhyKCP/KCPClient.cs
+++ b/Tests/KcpTests/SharedLib/KCP/MhyKCP/KCPClient.cs
@@ -1,6 +1,6 @@
using System.Net;
-using YYHEggEgg.Logger;
using csharp_Protoshift.SpecialUdp;
+using YYHEggEgg.Logger;
namespace csharp_Protoshift.MhyKCP
{
@@ -11,12 +11,12 @@ public class KCPClient : IDisposable
protected SocketUdpClient udpSock;
private bool _Closed = false;
protected MhyKcpBase server;
- protected IPEndPoint remoteAddress;
+ protected EndPoint remoteAddress;
protected SingleThreadAssert _recvlock = new($"{nameof(KCPClient)}_{nameof(Receive)}"),
_updatelock = new($"{nameof(KCPClient)}_{nameof(BackgroundUpdate)}");
- public KCPClient(IPEndPoint ipEp)
+ public KCPClient(EndPoint ipEp)
{
udpSock = new SocketUdpClient(true);
//udpSock = new();
@@ -76,7 +76,7 @@ protected virtual async Task BackgroundUpdate()
}
catch (Exception ex)
{
- Log.Erro($"Update fail: {ex}", nameof(KCPClient));
+ LogTrace.ErroTrace(ex, nameof(KCPClient), $"Update fail. ");
_Closed = true;
server.Dispose();
}
diff --git a/Tests/KcpTests/SharedLib/KCP/MhyKCP/KCPServer.cs b/Tests/KcpTests/SharedLib/KCP/MhyKCP/KCPServer.cs
index cd5b356c6..5e6975a5c 100644
--- a/Tests/KcpTests/SharedLib/KCP/MhyKCP/KCPServer.cs
+++ b/Tests/KcpTests/SharedLib/KCP/MhyKCP/KCPServer.cs
@@ -12,8 +12,7 @@ public class KCPServer : IDisposable
protected SocketUdpClient udpSock;
protected bool _Closed = false;
- // string is the ToString() form of IPEndPoint
- protected ConcurrentDictionary connecting_clients;
+ protected ConcurrentDictionary connecting_clients;
protected ConcurrentDictionary connected_clients;
protected ConcurrentQueue newConnections;
protected ConcurrentBag removed_sessions;
@@ -83,9 +82,8 @@ protected virtual async Task BackgroundUpdate()
continue;
}
// ip dispatch
- string remoteIpString = packet.RemoteEndPoint.ToString();
MhyKcpBase conn;
- if (!connecting_clients.TryGetValue(remoteIpString, out var _outconn))
+ if (!connecting_clients.TryGetValue(packet.RemoteEndPoint, out var _outconn))
{
// Don't allow a disconnected session
if (removed_sessions.Contains(handshake.Conv)) continue;
@@ -93,7 +91,7 @@ protected virtual async Task BackgroundUpdate()
conn = new MhyKcpBase();
conn.OutputCallback = new SocketUdpKcpCallback(udpSock, packet.RemoteEndPoint);
conn.AcceptNonblock();
- connecting_clients[remoteIpString] = conn;
+ connecting_clients[packet.RemoteEndPoint] = conn;
_ = Task.Run(async () =>
{
try
@@ -102,7 +100,7 @@ protected virtual async Task BackgroundUpdate()
}
catch
{
- connecting_clients.TryRemove(remoteIpString, out _);
+ connecting_clients.TryRemove(packet.RemoteEndPoint, out _);
}
});
}
diff --git a/Tests/KcpTests/SharedLib/KCP/MhyKCP/KcpInnerBuffer.cs b/Tests/KcpTests/SharedLib/KCP/MhyKCP/KcpInnerBuffer.cs
index e1799eb12..20756fe95 100644
--- a/Tests/KcpTests/SharedLib/KCP/MhyKCP/KcpInnerBuffer.cs
+++ b/Tests/KcpTests/SharedLib/KCP/MhyKCP/KcpInnerBuffer.cs
@@ -1,4 +1,4 @@
-using System.Buffers;
+using System.Buffers;
namespace csharp_Protoshift.MhyKCP
{
diff --git a/Tests/KcpTests/SharedLib/KCP/MhyKCP/KcpPacketAudit.cs b/Tests/KcpTests/SharedLib/KCP/MhyKCP/KcpPacketAudit.cs
index 9d4d2f3cd..9c3f1e2aa 100644
--- a/Tests/KcpTests/SharedLib/KCP/MhyKCP/KcpPacketAudit.cs
+++ b/Tests/KcpTests/SharedLib/KCP/MhyKCP/KcpPacketAudit.cs
@@ -1,9 +1,10 @@
-#define MIHOMO_KCP
+#define MIHOMO_KCP
using System.Buffers;
using System.Buffers.Binary;
using System.Collections.Concurrent;
using System.Diagnostics;
+using System.IO.Hashing;
using System.Net.Sockets.Kcp;
using System.Text;
using YYHEggEgg.Logger;
@@ -98,6 +99,10 @@ private static void BackgroundUpdate()
offset += sizeof(byte) + sizeof(ushort) + sizeof(uint) * 3;
uint len = BinaryPrimitives.ReadUInt32LittleEndian(segment.Slice(offset));
offset += sizeof(uint);
+#if BYTE_CHECK_MODE
+ uint byteCheckCode = BinaryPrimitives.ReadUInt32LittleEndian(segment.Slice(offset));
+ offset += sizeof(uint);
+#endif
Debug.Assert(offset == KcpConst.IKCP_OVERHEAD);
#endregion
#region Content Length Check
@@ -115,6 +120,16 @@ private static void BackgroundUpdate()
Convert.ToHexString(segment.Slice(
(int)(offset + len), (int)(contentLen - len))));
}
+#if BYTE_CHECK_MODE && !CORRUPT_PACKET
+ else
+ {
+ var checksum = Crc32.HashToUInt32(segment.Slice(offset));
+ if (byteCheckCode != checksum)
+ {
+ exceptions.Add($"Segment {i} byte check (CRC32) failed, expected: {byteCheckCode}, actual: {checksum}.");
+ }
+ }
+#endif
#endregion
}
}
@@ -149,7 +164,7 @@ private static void BackgroundUpdate()
#if MIHOMO_KCP
offset += sizeof(uint) * 2;
#else
- offset += sizeof(uint);
+ offset += sizeof(uint);
#endif
byte cmd = segment[offset];
offset += sizeof(byte);
@@ -165,6 +180,10 @@ private static void BackgroundUpdate()
offset += sizeof(uint);
uint len = BinaryPrimitives.ReadUInt32LittleEndian(segment.Slice(offset));
offset += sizeof(uint);
+#if BYTE_CHECK_MODE
+ uint byteCheckCode = BinaryPrimitives.ReadUInt32LittleEndian(segment.Slice(offset));
+ offset += sizeof(uint);
+#endif
Debug.Assert(offset == KcpConst.IKCP_OVERHEAD);
#endregion
#region Output segment
@@ -181,7 +200,8 @@ private static void BackgroundUpdate()
}
catch (Exception ex)
{
- Log.Erro($"Error occured when handling audit kcp packet: {ex}", nameof(KcpPacketAudit));
+ LogTrace.ErroTrace(ex, nameof(KcpPacketAudit),
+ $"Error occured when handling audit kcp packet. ");
}
}
}
diff --git a/Tests/KcpTests/SharedLib/KCP/MhyKCP/MhyKcpBase.cs b/Tests/KcpTests/SharedLib/KCP/MhyKCP/MhyKcpBase.cs
index 5c5c357a3..ab530c3e2 100644
--- a/Tests/KcpTests/SharedLib/KCP/MhyKCP/MhyKcpBase.cs
+++ b/Tests/KcpTests/SharedLib/KCP/MhyKCP/MhyKcpBase.cs
@@ -1,4 +1,4 @@
-// #define KCP_INNER_LOG
+// #define KCP_INNER_LOG
// #define KCP_EXPORT_PACKET_RECORD
using System.Net.Sockets;
@@ -54,6 +54,11 @@ public enum ConnectionState
protected object cskcp_recvLock = "R.I.P YSFreedom";
protected object cskcp_sndLock = "Yolmiya";
protected long startTime;
+ ///
+ /// Used for assigning conv for new connections.
+ /// Use to operate with it.
+ ///
+ protected static uint _currentConv = 1000;
public uint ConnectData { get; protected set; }
public OuterCode.UniqueIDManager _uniqueID = new(nameof(MhyKcpBase));
@@ -75,6 +80,15 @@ public void Initialize()
cskcpHandle = new(_Conv, _Token, OutputCallback);
_State = ConnectionState.CONNECTED;
+#if BYTE_CHECK_MODE
+#if CORRUPT_PACKET
+ bool corrupt = true;
+#else
+ bool corrupt = false;
+#endif
+ cskcpHandle.SetByteCheck(2, corrupt);
+#endif
+
// Added
// IKCP.ikcp_nodelay(ikcpHandle, 1, 10, 2, 1);
// modified because mhy is using far more aggressive code, or 力大砖飞 mode
@@ -187,7 +201,7 @@ public virtual int Input(byte[] buffer)
{
// Log.Dbug($"HandShakeWaitNotify, buf = {Convert.ToHexString(buffer)}", nameof(MhyKcpBase));
handshake.Decode(buffer, Handshake.MAGIC_CONNECT);
- _Conv = (uint)(MonotonicTime.Now & 0xFFFFFFFF);
+ _Conv = Interlocked.Increment(ref _currentConv);
_Token = 0xFFCCEEBB ^ (uint)((MonotonicTime.Now >> 32) & 0xFFFFFFFF);
var sendBackConv = new Handshake(Handshake.MAGIC_SEND_BACK_CONV, _Conv, _Token).AsBytes();
@@ -366,7 +380,8 @@ public async Task BackgroundUpdate()
catch (Exception ex)
{
_updatelock.Exit();
- Log.Erro($"MhyKcpBase Background Check/Update exception and restart: {ex}", nameof(MhyKcpBase));
+ LogTrace.ErroTrace(ex, nameof(MhyKcpBase),
+ $"MhyKcpBase Background Check/Update exception and restart. ");
_ = Task.Run(BackgroundUpdate);
}
}
diff --git a/Tests/KcpTests/SharedLib/KCP/MhyKCP/UdpKcpCallback.cs b/Tests/KcpTests/SharedLib/KCP/MhyKCP/UdpKcpCallback.cs
index 5e63ccce1..a234190a9 100644
--- a/Tests/KcpTests/SharedLib/KCP/MhyKCP/UdpKcpCallback.cs
+++ b/Tests/KcpTests/SharedLib/KCP/MhyKCP/UdpKcpCallback.cs
@@ -1,6 +1,5 @@
-#define KCP_PACKET_AUDIT
+// #define KCP_PACKET_AUDIT
-using csharp_Protoshift.Obsoleted.SpecialUdp;
using csharp_Protoshift.SpecialUdp;
using System.Buffers;
using System.Diagnostics;
@@ -31,25 +30,6 @@ public void Output(IMemoryOwner buffer, int avalidLength, bool isKcpPacket
}
}
- [Obsolete]
- public class ConcurrentUdpKcpCallback : IKcpCallback
- {
- private readonly ConcurrentUdpClient udpSock;
- private readonly IPEndPoint? ipEp;
-
- public ConcurrentUdpKcpCallback(ConcurrentUdpClient udpSock, IPEndPoint? ipEp = null)
- {
- this.udpSock = udpSock;
- this.ipEp = ipEp;
- }
-
- public async void Output(IMemoryOwner buffer, int avalidLength, bool isKcpPacket = true)
- {
- await udpSock.SendAsync(buffer.Memory.Slice(0, avalidLength), ipEp);
- buffer.Dispose();
- }
- }
-
public class SocketUdpKcpCallback : IKcpCallback
{
private readonly SocketUdpClient udpSock;
@@ -64,11 +44,15 @@ public SocketUdpKcpCallback(SocketUdpClient udpSock, IPEndPoint? ipEp = null)
public void Output(IMemoryOwner buffer, int avalidLength, bool isKcpPacket = true)
{
// Stopwatch udpwatch = Stopwatch.StartNew();
- // DateTime req_SendTime = DateTime.Now;
+#if KCP_PACKET_AUDIT
+ DateTime req_SendTime = DateTime.Now;
+#endif
// udpSock.SendToAsync(buffer.Memory.Slice(0, avalidLength), ipEp).Wait();
udpSock.SendTo(buffer.Memory.Span.Slice(0, avalidLength), ipEp);
- // if (isKcpPacket)
- // KcpPacketAudit.PushPacket(req_SendTime, buffer.Memory, avalidLength);
+#if KCP_PACKET_AUDIT
+ if (isKcpPacket)
+ KcpPacketAudit.PushPacket(req_SendTime, buffer.Memory, avalidLength);
+#endif
buffer.Dispose();
// udpwatch.Stop();
// Log.Dbug($"SocketUdpKcpCallback output elapsed {udpwatch.Elapsed.TotalMilliseconds}ms.");
diff --git a/Tests/KcpTests/SharedLib/KCP/SingleThreadAssert.cs b/Tests/KcpTests/SharedLib/KCP/SingleThreadAssert.cs
index 70d055d62..15037ea68 100644
--- a/Tests/KcpTests/SharedLib/KCP/SingleThreadAssert.cs
+++ b/Tests/KcpTests/SharedLib/KCP/SingleThreadAssert.cs
@@ -1,4 +1,4 @@
-using YYHEggEgg.Logger;
+using YYHEggEgg.Logger;
namespace csharp_Protoshift
{
diff --git a/Tests/KcpTests/SharedLib/KCP/SpecialUdp/Obsoleted/ConcurrentUdpClient.cs b/Tests/KcpTests/SharedLib/KCP/SpecialUdp/Obsoleted/ConcurrentUdpClient.cs
deleted file mode 100644
index 47780ed4a..000000000
--- a/Tests/KcpTests/SharedLib/KCP/SpecialUdp/Obsoleted/ConcurrentUdpClient.cs
+++ /dev/null
@@ -1,495 +0,0 @@
-// Generated by ChatGPT
-#define SPECIAL_UDP_VERBOSE
-#define SPECIAL_UDP_WARNING
-
-#pragma warning disable CS8604 // 引用类型参数可能为 null。
-#pragma warning disable CS8629 // 可为 null 的值类型可为 null。
-#pragma warning disable CS8625 // 无法将 null 字面量转换为非 null 的引用类型。
-
-using System.Collections.Concurrent;
-using System.Diagnostics;
-using System.Net;
-using System.Net.Sockets;
-using YYHEggEgg.Logger;
-
-// Obsoleted for bad performance
-namespace csharp_Protoshift.Obsoleted.SpecialUdp
-{
- public sealed class ConcurrentUdpClient : IDisposable
- {
- #region Packet Utils
- private enum UdpInvoke
- {
- ///
- /// Equal to .
- ///
- SendConnected = 1,
- ///
- /// Equal to .
- ///
- SendAnyEndpoint = 2,
- ///
- /// Equal to .
- ///
- SendAsyncConnected = 11,
- ///
- /// Equal to .
- ///
- SendAsyncAnyEndpoint = 12,
- ///
- /// Equal to .
- ///
- SendAsyncMemoryConnected = 13,
- ///
- /// Equal to .
- ///
- SendAsyncMemoryAnyEndpoint = 14,
- ///
- /// Equal to .
- ///
- Receive = 101,
- ///
- /// Equal to .
- ///
- ReceiveAsync = 111
- }
-
- private class UdpSendPacket
- {
- public byte[]? data;
- public ReadOnlyMemory? memoryData;
- public int? bytes;
- public IPEndPoint? endpoint;
- public Exception? ex;
- public int? rtn;
- public UdpInvoke invoke;
-
- public UdpSendPacket(byte[] data, int bytes, IPEndPoint? endpoint, UdpInvoke invoke)
- {
- this.data = data;
- this.bytes = bytes;
- this.endpoint = endpoint;
- this.invoke = invoke;
- }
-
- public UdpSendPacket(ReadOnlyMemory memoryData, IPEndPoint? endpoint, UdpInvoke invoke)
- {
- this.memoryData = memoryData;
- this.endpoint = endpoint;
- this.invoke = invoke;
- }
- }
-
- private class UdpReceivePacket
- {
- public UdpReceiveResult? receiveData;
- public Exception? ex;
- public UdpInvoke invoke;
-
- public UdpReceivePacket(UdpInvoke invoke)
- {
- this.invoke = invoke;
- }
- }
- #endregion
-
- #region BeforeHand Initialize
- // 构造函数
- public ConcurrentUdpClient()
- {
- // 初始化UdpClient实例
- baseClient = new UdpClient();
-#if SPECIAL_UDP_VERBOSE
- Log.Info("baseClient initialized with normal paramters.", "ConcurrentUdpClient");
-#endif
- // 启动后台更新任务
- Task.Run(BackgroundUpdate);
- }
-
- public ConcurrentUdpClient(IPEndPoint bindAddress)
- {
- baseClient = new UdpClient(bindAddress);
-#if SPECIAL_UDP_VERBOSE
- Log.Info($"baseClient initialized with ipEp:{bindAddress}.", "ConcurrentUdpClient");
-#endif
- Task.Run(BackgroundUpdate);
- }
-
- public void Connect(IPEndPoint ipEp)
- {
- ConnectedAddress = ipEp;
-#if SPECIAL_UDP_VERBOSE
- Log.Info($"baseClient Connected to ipEp:{ipEp}.", "ConcurrentUdpClient");
-#endif
- baseClient.Connect(ipEp);
- }
- #endregion
-
- // 发送队列
- private ConcurrentQueue qSend = new();
- // 接收队列
- private ConcurrentQueue qRecv = new();
- // 内部使用的UdpClient实例
- private UdpClient baseClient;
- public IPEndPoint? ConnectedAddress { get; set; }
-
- public int RefreshMilliseconds = 10;
-
- #region Receive Packet
- public byte[] Receive(ref IPEndPoint fromip)
- {
-#if SPECIAL_UDP_VERBOSE
- Log.Info($"User tried to invoke Receive().", "ConcurrentUdpClient");
-#endif
- var handle = new UdpReceivePacket(UdpInvoke.Receive);
- qRecv.Enqueue(handle);
- while (true)
- {
- if (handle.receiveData != null)
- {
-#if SPECIAL_UDP_VERBOSE
- Log.Info($"Successfully received {((UdpReceiveResult)handle.receiveData).Buffer.Length} bytes in Receive().", "ConcurrentUdpClient");
-#endif
- fromip = ((UdpReceiveResult)handle.receiveData).RemoteEndPoint;
- return ((UdpReceiveResult)handle.receiveData).Buffer;
- }
- if (handle.ex != null) throw handle.ex;
- Task.Delay(RefreshMilliseconds).Wait();
- }
- }
-
- public async Task ReceiveAsync()
- {
-#if SPECIAL_UDP_VERBOSE
- Log.Info($"User tried to invoke ReceiveAsync().", "ConcurrentUdpClient");
-#endif
- var handle = new UdpReceivePacket(UdpInvoke.Receive);
- qRecv.Enqueue(handle);
- while (true)
- {
- if (handle.receiveData != null)
- {
-#if SPECIAL_UDP_VERBOSE
- Log.Info($"Successfully received {((UdpReceiveResult)handle.receiveData).Buffer.Length} bytes in ReceiveAsync().", "ConcurrentUdpClient");
-#endif
- return (UdpReceiveResult)handle.receiveData;
- }
- if (handle.ex != null) throw handle.ex;
- await Task.Delay(RefreshMilliseconds);
- }
- }
- #endregion
-
- #region Send Packet
- public int Send(byte[] data, int? bytes = null, IPEndPoint? endpoint = null)
- {
-#if SPECIAL_UDP_VERBOSE
- Log.Info($"User tried to invoke Send() with {data.Length} bytes to {endpoint}.", "ConcurrentUdpClient");
-#endif
- if (endpoint == null && ConnectedAddress == null)
- // WSAENOTCONN, socket not connected
- throw new SocketException(10057);
- bytes ??= data.Length;
- var handle = new UdpSendPacket(data, (int)bytes, endpoint,
- endpoint == null ? UdpInvoke.SendConnected : UdpInvoke.SendAnyEndpoint);
- qSend.Enqueue(handle);
- while (true)
- {
- if (handle.rtn != null)
- {
- if (handle.ex != null)
- {
-#if SPECIAL_UDP_VERBOSE
- Log.Dbug("Invoke Send() throwed an exception.", "ConcurrentUdpClient");
-#endif
- // 如果有异常则抛出
- throw handle.ex;
- }
-#if SPECIAL_UDP_VERBOSE
- Log.Dbug($"Invoke Send() returned {handle.rtn}.", "ConcurrentUdpClient");
-#endif
- return (int)handle.rtn;
- }
- Task.Delay(RefreshMilliseconds).Wait();
- }
- }
-
- public async Task SendAsync(byte[] data, int? bytes = null, IPEndPoint? endpoint = null)
- {
-#if SPECIAL_UDP_VERBOSE
- Log.Info($"User tried to invoke SendAsync() with {data.Length} bytes to {endpoint}.", "ConcurrentUdpClient");
-#endif
- if (endpoint == null && ConnectedAddress == null)
- // WSAENOTCONN, socket not connected
- throw new SocketException(10057);
- bytes ??= data.Length;
- var handle = new UdpSendPacket(data, (int)bytes, endpoint,
- endpoint == null ? UdpInvoke.SendAsyncConnected : UdpInvoke.SendAsyncAnyEndpoint);
- qSend.Enqueue(handle);
- while (true)
- {
- if (handle.rtn != null)
- {
- if (handle.ex != null)
- {
-#if SPECIAL_UDP_VERBOSE
- Log.Dbug("Invoke SendAsync() throwed an exception.", "ConcurrentUdpClient");
-#endif
- // 如果有异常则抛出
- throw handle.ex;
- }
-#if SPECIAL_UDP_VERBOSE
- Log.Dbug($"Invoke SendAsync() returned {handle.rtn}.", "ConcurrentUdpClient");
-#endif
- return (int)handle.rtn;
- }
- await Task.Delay(10);
- }
- }
-
- public async Task SendAsync(ReadOnlyMemory data, IPEndPoint? endpoint = null)
- {
-#if SPECIAL_UDP_VERBOSE
- Log.Info($"User tried to invoke SendAsync() with {data.Length} bytes to {endpoint}.", "ConcurrentUdpClient");
-#endif
- if (endpoint == null && ConnectedAddress == null)
- // WSAENOTCONN, socket not connected
- throw new SocketException(10057);
- var handle = new UdpSendPacket(data, endpoint,
- endpoint == null ? UdpInvoke.SendAsyncMemoryConnected : UdpInvoke.SendAsyncMemoryAnyEndpoint);
- qSend.Enqueue(handle);
- while (true)
- {
- if (handle.rtn != null)
- {
- if (handle.ex != null)
- {
-#if SPECIAL_UDP_VERBOSE
- Log.Dbug("Invoke SendAsync() throwed an exception.", "ConcurrentUdpClient");
-#endif
- // 如果有异常则抛出
- throw handle.ex;
- }
-#if SPECIAL_UDP_VERBOSE
- Log.Dbug($"Invoke SendAsync() returned {handle.rtn}.", "ConcurrentUdpClient");
-#endif
- return (int)handle.rtn;
- }
- await Task.Delay(10);
- }
- }
- #endregion
-
- #region Background Handler
- // 后台更新任务
- private async Task BackgroundUpdate()
- {
- if (qSend.TryDequeue(out UdpSendPacket? sendpacket))
- {
-#if SPECIAL_UDP_VERBOSE
- Stopwatch watch = new();
- bool exHappened = false;
- watch.Start();
-#endif
- try
- {
- // 发送数据
- switch (sendpacket.invoke)
- {
- case UdpInvoke.SendConnected:
- sendpacket.rtn = baseClient.Send(
- sendpacket.data, (int)sendpacket.bytes);
- break;
- case UdpInvoke.SendAnyEndpoint:
- sendpacket.rtn = baseClient.Send(
- sendpacket.data, (int)sendpacket.bytes, sendpacket.endpoint);
- break;
- case UdpInvoke.SendAsyncConnected:
- sendpacket.rtn = await baseClient.SendAsync(
- sendpacket.data, (int)sendpacket.bytes);
- break;
- case UdpInvoke.SendAsyncAnyEndpoint:
- sendpacket.rtn = await baseClient.SendAsync(
- sendpacket.data, (int)sendpacket.bytes, sendpacket.endpoint);
- break;
- case UdpInvoke.SendAsyncMemoryConnected:
- sendpacket.rtn = await baseClient.SendAsync(
- (ReadOnlyMemory)sendpacket.memoryData);
- break;
- case UdpInvoke.SendAsyncMemoryAnyEndpoint:
- sendpacket.rtn = await baseClient.SendAsync(
- (ReadOnlyMemory)sendpacket.memoryData, sendpacket.endpoint);
- break;
- default:
- Log.Erro($"Receive packet accidently ran into send queue," +
- $"Invoke:{sendpacket.invoke}, packet[{sendpacket.bytes}]:" +
- Convert.ToHexString(sendpacket.data), "ConcurrentUdpClient");
- break;
- }
- }
- catch (Exception ex)
- {
- sendpacket.ex = ex;
- sendpacket.rtn = -1;
-#if SPECIAL_UDP_VERBOSE
- exHappened = true;
-#endif
- }
-#if SPECIAL_UDP_VERBOSE
- watch.Stop();
- Log.Dbug($"Handle qSend {(exHappened ? "(Exception)" : string.Empty)} " +
- $"costed {watch.ElapsedMilliseconds}ms.", "ConcurrentUdpClient");
-#endif
- }
- else if (baseClient.Available > 0
- && qRecv.TryPeek(out UdpReceivePacket? receivepacket))
- {
-#if SPECIAL_UDP_VERBOSE
- Stopwatch watch = new();
- bool exHappened = false;
- bool timeout = false;
- watch.Start();
-#endif
- switch (receivepacket.invoke)
- {
- case UdpInvoke.Receive:
- try
- {
- IPEndPoint ipEp = new(IPAddress.Loopback, 0);
-#if SPECIAL_UDP_WARNING || SPECIAL_UDP_VERBOSE
- Stopwatch cancelwatch = new();
- cancelwatch.Start();
-#endif
- byte[] buf = baseClient.Receive(ref ipEp);
-#if SPECIAL_UDP_WARNING || SPECIAL_UDP_VERBOSE
- cancelwatch.Stop();
- if (cancelwatch.ElapsedMilliseconds > 40)
- {
- Log.Warn("Syncronous Receive() stuck for " +
- $"{cancelwatch.ElapsedMilliseconds}ms!", "ConcurrentUdpClient");
-#endif
-#if SPECIAL_UDP_VERBOSE
- timeout = true;
-#endif
-#if SPECIAL_UDP_WARNING || SPECIAL_UDP_VERBOSE
- }
-#endif
- receivepacket.receiveData = new(buf, ipEp);
- qRecv.TryDequeue(out _);
-#if SPECIAL_UDP_VERBOSE
- Log.Dbug($"Background qRecv handle received {buf.Length} bytes.", "ConcurrentUdpClient");
-#endif
- }
- catch (Exception ex)
- {
- receivepacket.ex = ex;
- qRecv.TryDequeue(out _);
-#if SPECIAL_UDP_VERBOSE
- exHappened = true;
-#endif
- }
- break;
- case UdpInvoke.ReceiveAsync:
- var cancellationTokenSource = new CancellationTokenSource();
- var captureToken = cancellationTokenSource.Token;
- try
- {
- cancellationTokenSource.CancelAfter(50);
- UdpReceiveResult res = await baseClient.ReceiveAsync(captureToken);
- receivepacket.receiveData = res;
- qRecv.TryDequeue(out _);
-#if SPECIAL_UDP_VERBOSE
- Log.Dbug($"Background qRecv handle(async) received {res.Buffer.Length} bytes.", "ConcurrentUdpClient");
-#endif
- }
- catch (OperationCanceledException)
- {
-#if SPECIAL_UDP_WARNING || SPECIAL_UDP_VERBOSE
- Log.Warn("Asyncronous ReceiveAsync() timeout of 50ms and canceled!", "ConcurrentUdpClient");
-#endif
-#if SPECIAL_UDP_VERBOSE
- timeout = true;
-#endif
- }
- catch (Exception ex)
- {
- receivepacket.ex = ex;
- qRecv.TryDequeue(out _);
-#if SPECIAL_UDP_VERBOSE
- exHappened = true;
-#endif
- }
- break;
- default:
- Log.Erro("Send packet accidently ran into receive queue," +
- $"Invoke:{receivepacket.invoke}", "ConcurrentUdpClient");
- qRecv.TryDequeue(out _);
- break;
- }
-#if SPECIAL_UDP_VERBOSE
- watch.Stop();
- Log.Dbug($"Handle qRecv {(exHappened ? "(Exception)" : string.Empty)} " +
- $"costed {watch.ElapsedMilliseconds}ms." +
- (timeout ? " (timed out) " : string.Empty), "ConcurrentUdpClient");
-#endif
- }
- else
- {
- // 等待一段时间,降低CPU占用
- await Task.Delay(5);
- }
- await Task.Run(BackgroundUpdate);
- }
- #endregion
-
- #region IDisposeable
- /* Generated by ChatGPT
- * 在上面的代码中,我们实现了Close()、Dispose()和Protected Dispose(bool)方法,并且实现了IDisposeable接口。
- * 它们的作用如下:
-
- * - Close()方法:关闭基础UDP客户端。
- * - Dispose()方法:释放托管资源和非托管资源。
- * 这个方法由垃圾回收器调用,也可以由开发人员主动调用。
- * 在这里,我们在调用Dispose()方法时通过调用Dispose(true)方法释放托管资源,
- * 并抑制GC.SuppressFinalize(this)来防止使用Finalizer。
- * - Protected Dispose(bool)方法:释放非托管资源。
- * 如果disposing为true,则还会释放托管资源。
-
- * 需要注意的是,我们在类定义中还定义了一个Finalizer(也就是析构函数)。
- * 这个Finalizer中调用了Dispose(false)方法,以释放非托管资源。
- * 这样做是为了确保即使开发人员没有调用Dispose()方法,也能在对象被垃圾回收前释放非托管资源。
- */
- public void Close()
- {
- baseClient.Close();
- }
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- private void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (baseClient != null)
- {
- baseClient.Dispose();
- baseClient = null;
- }
- }
- }
-
- ~ConcurrentUdpClient()
- {
- Dispose(false);
- }
- #endregion
- }
-}
-
-#pragma warning restore CS8604 // 引用类型参数可能为 null。
-#pragma warning restore CS8629 // 可为 null 的值类型可为 null。
-#pragma warning restore CS8625 // 无法将 null 字面量转换为非 null 的引用类型。
\ No newline at end of file
diff --git a/Tests/KcpTests/SharedLib/KCP/SpecialUdp/SocketUdpClient.cs b/Tests/KcpTests/SharedLib/KCP/SpecialUdp/SocketUdpClient.cs
index 0b52ab6e1..2e8dfc862 100644
--- a/Tests/KcpTests/SharedLib/KCP/SpecialUdp/SocketUdpClient.cs
+++ b/Tests/KcpTests/SharedLib/KCP/SpecialUdp/SocketUdpClient.cs
@@ -1,4 +1,4 @@
-// #define SOCKET_UDP_VERBOSE
+// #define SOCKET_UDP_VERBOSE
// #define SOCKET_UDP_PACKET_CONTENT_VERBOSE
// #define SOCKET_UDP_PACKET_CONTENT_VERBOSE_SYNCRONOUS
@@ -13,7 +13,7 @@ namespace csharp_Protoshift.SpecialUdp
public class SocketUdpClient : IDisposable
{
private readonly Socket _socket;
- private IPEndPoint? _defaultEndpoint;
+ private EndPoint? _defaultEndpoint;
private string? _defaultEndpointString;
public const int UDP_MAX_PACKET_SIZE = 65507;
@@ -23,14 +23,17 @@ public class SocketUdpClient : IDisposable
private byte[]? STABuffer;
private SingleThreadAssert? _rcvSTAAssert;
+ private readonly bool isIpv6Socket;
+
///
/// Initializer.
///
/// means you confirm that you're invoking the in only one thread. If you give it true but not ensure that, terrible thing will happen.
- public SocketUdpClient(bool singlethread_receiving = false)
+ public SocketUdpClient(bool singlethread_receiving = false, bool isIpv6Socket = false)
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- _socket.Bind(new IPEndPoint(IPAddress.Any, 0));
+ this.isIpv6Socket = isIpv6Socket;
+ _socket.Bind(DefaultEndPoint);
_arrayPool = ArrayPool.Shared;
_isSTABuffer = singlethread_receiving;
if (_isSTABuffer)
@@ -38,16 +41,23 @@ public SocketUdpClient(bool singlethread_receiving = false)
STABuffer = new byte[UDP_MAX_PACKET_SIZE];
_rcvSTAAssert = new($"{nameof(SocketUdpClient)}_{ReceiveFrom}");
}
+
}
public SocketUdpClient(IPEndPoint ipEndPoint, bool singlethread_receiving = false)
{
if (ipEndPoint.AddressFamily == AddressFamily.InterNetwork)
+ {
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
+ isIpv6Socket = false;
+ }
else if (ipEndPoint.AddressFamily == AddressFamily.InterNetworkV6)
+ {
_socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
+ isIpv6Socket = true;
+ }
else throw new ArgumentException(
- "IPEndPoint is probably not a valid IP address or used, please check the input",
+ "IPEndPoint is probably not a valid IP address or used, please check the input",
nameof(ipEndPoint));
_socket.Bind(ipEndPoint);
_arrayPool = ArrayPool.Shared;
@@ -59,9 +69,11 @@ public SocketUdpClient(IPEndPoint ipEndPoint, bool singlethread_receiving = fals
}
}
- public void Connect(IPEndPoint ipEndPoint)
+ private IPEndPoint DefaultEndPoint => new IPEndPoint(isIpv6Socket ? IPAddress.IPv6Any : IPAddress.Any, 0);
+
+ public void Connect(EndPoint endPoint)
{
- _defaultEndpoint = ipEndPoint;
+ _defaultEndpoint = endPoint;
_defaultEndpointString = _defaultEndpoint.ToString();
}
@@ -85,7 +97,7 @@ public SocketUdpReceiveResult ReceiveFrom()
var stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
#endif
- EndPoint _tmpendp = new IPEndPoint(IPAddress.Any, 0);
+ EndPoint _tmpendp = DefaultEndPoint;
var avalidlength = _socket.ReceiveFrom(buffer, SocketFlags.None,
ref _tmpendp);
@@ -132,7 +144,7 @@ public SocketUdpReceiveResult ReceiveFrom()
}
catch (Exception ex)
{
- Log.Warn($"Failed to receive packet: {ex}", nameof(SocketUdpClient));
+ LogTrace.WarnTrace(ex, nameof(SocketUdpClient), $"Failed to receive packet. ");
throw;
}
finally
@@ -155,7 +167,7 @@ public async Task ReceiveFromAsync()
#pragma warning restore CS8600, CS8602
}
else buffer = _arrayPool.Rent(UDP_MAX_PACKET_SIZE);
- SocketUdpReceiveResult receiveResult = new();
+ SocketUdpReceiveResult receiveResult = new() { RemoteEndPoint = DefaultEndPoint };
try
{
@@ -210,7 +222,7 @@ public async Task ReceiveFromAsync()
}
catch (Exception ex)
{
- Log.Warn($"Failed to receive packet: {ex}", nameof(SocketUdpClient));
+ LogTrace.WarnTrace(ex, nameof(SocketUdpClient), $"Failed to receive packet. ");
throw;
}
finally
@@ -224,7 +236,7 @@ public async Task ReceiveFromAsync()
#endregion
#region SendTo
- public int SendTo(byte[] buffer, IPEndPoint? ipEndPoint = null)
+ public int SendTo(byte[] buffer, EndPoint? ipEndPoint = null)
{
if (ipEndPoint == null && _defaultEndpoint == null)
{
@@ -264,12 +276,12 @@ public int SendTo(byte[] buffer, IPEndPoint? ipEndPoint = null)
}
catch (Exception ex)
{
- Log.Erro($"Failed to send packet: {ex.Message}", nameof(SocketUdpClient));
+ LogTrace.InfoTrace(ex, nameof(SocketUdpClient), $"Failed to send packet. ");
throw;
}
}
- public int SendTo(ReadOnlySpan buffer, IPEndPoint? ipEndPoint = null)
+ public int SendTo(ReadOnlySpan buffer, EndPoint? ipEndPoint = null)
{
if (ipEndPoint == null && _defaultEndpoint == null)
{
@@ -304,14 +316,14 @@ public int SendTo(ReadOnlySpan buffer, IPEndPoint? ipEndPoint = null)
}
catch (Exception ex)
{
- Log.Erro($"Failed to send packet: {ex.Message}", nameof(SocketUdpClient));
+ LogTrace.InfoTrace(ex, nameof(SocketUdpClient), $"Failed to send packet. ");
throw;
}
}
#endregion
#region SendToAsync
- public async Task SendToAsync(ReadOnlyMemory buffer, IPEndPoint? ipEndPoint = null)
+ public async Task SendToAsync(ReadOnlyMemory buffer, EndPoint? ipEndPoint = null)
{
if (ipEndPoint == null && _defaultEndpoint == null)
{
@@ -351,12 +363,12 @@ public async Task SendToAsync(ReadOnlyMemory buffer, IPEndPoint? ipEn
}
catch (Exception ex)
{
- Log.Erro($"Failed to send packet: {ex.Message}", nameof(SocketUdpClient));
+ LogTrace.InfoTrace(ex, nameof(SocketUdpClient), $"Failed to send packet. ");
throw;
}
}
- public async Task SendToAsync(byte[] buffer, IPEndPoint? ipEndPoint = null)
+ public async Task SendToAsync(byte[] buffer, EndPoint? ipEndPoint = null)
{
if (ipEndPoint == null && _defaultEndpoint == null)
{
@@ -396,7 +408,7 @@ public async Task SendToAsync(byte[] buffer, IPEndPoint? ipEndPoint = null)
}
catch (Exception ex)
{
- Log.Erro($"Failed to send packet: {ex.Message}", nameof(SocketUdpClient));
+ LogTrace.InfoTrace(ex, nameof(SocketUdpClient), $"Failed to send packet. ");
throw;
}
}
@@ -429,12 +441,10 @@ public void Close()
public class SocketUdpReceiveResult
{
- private static IPEndPoint defaultIpEp = new IPEndPoint(IPAddress.Any, 0);
-
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public byte[] Buffer;
-#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public int ReceivedBytes;
- public IPEndPoint RemoteEndPoint = defaultIpEp;
+ public IPEndPoint RemoteEndPoint;
+#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
}
}
\ No newline at end of file
diff --git a/Tests/KcpTests/SharedLib/SharedLib.csproj b/Tests/KcpTests/SharedLib/SharedLib.csproj
index 79a9ba15a..a5fe4e4fd 100644
--- a/Tests/KcpTests/SharedLib/SharedLib.csproj
+++ b/Tests/KcpTests/SharedLib/SharedLib.csproj
@@ -7,17 +7,18 @@
- $(DefineConstants);KCP_PERFORMANCE_TEST;STA_ASSERT_DISABLED
+ $(DefineConstants);KCP_PERFORMANCE_TEST;DISABLED_BYTE_CHECK_MODE;STA_ASSERT_DISABLED
- $(DefineConstants);KCP_PERFORMANCE_TEST;STA_ASSERT_DISABLED
+ $(DefineConstants);KCP_PERFORMANCE_TEST;DISABLED_BYTE_CHECK_MODE;STA_ASSERT_DISABLED
-
+
+
diff --git a/Tests/ProtoshiftBenchmark/ProtoshiftBenchmark.csproj b/Tests/ProtoshiftBenchmark/ProtoshiftBenchmark.csproj
index 921936af7..2d29db842 100644
--- a/Tests/ProtoshiftBenchmark/ProtoshiftBenchmark.csproj
+++ b/Tests/ProtoshiftBenchmark/ProtoshiftBenchmark.csproj
@@ -18,7 +18,7 @@
-
+
diff --git a/Tests/csharp-Protoshift-Replay/csharp-Protoshift-Replay.csproj b/Tests/csharp-Protoshift-Replay/csharp-Protoshift-Replay.csproj
index 125627098..91642f56e 100644
--- a/Tests/csharp-Protoshift-Replay/csharp-Protoshift-Replay.csproj
+++ b/Tests/csharp-Protoshift-Replay/csharp-Protoshift-Replay.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/csharp-Protoshift/Commands/Utils/Dispatch/CurrRegionCmd.cs b/csharp-Protoshift/Commands/Utils/Dispatch/CurrRegionCmd.cs
index 82140df7d..95d00ce57 100644
--- a/csharp-Protoshift/Commands/Utils/Dispatch/CurrRegionCmd.cs
+++ b/csharp-Protoshift/Commands/Utils/Dispatch/CurrRegionCmd.cs
@@ -2,6 +2,7 @@
using csharp_Protoshift.resLoader;
using Google.Protobuf;
using Newtonsoft.Json;
+using YYHEggEgg.Logger;
namespace csharp_Protoshift.Commands.Utils
{
diff --git a/csharp-Protoshift/GameSession/GameSessionDispatch.cs b/csharp-Protoshift/GameSession/GameSessionDispatch.cs
index 2d30514a6..7726d2841 100644
--- a/csharp-Protoshift/GameSession/GameSessionDispatch.cs
+++ b/csharp-Protoshift/GameSession/GameSessionDispatch.cs
@@ -28,7 +28,7 @@ public static void SessionCreated(uint conv, IPEndPoint ipEp)
}
else sessions[conv].remoteIp = ipEp;
}
- BackgroundInjectOnlineExecuteWindys(conv,
+ BackgroundInjectOnlineExecuteWindys(conv,
OnlineExecWindyMode_v1_0_0.OnKcpConnect, "windyOnKcpConnect");
}
@@ -147,7 +147,7 @@ public static async Task InjectOnlineExecuteWindys(uint conv, OnlineExecWindyMod
public static void BackgroundInjectOnlineExecuteWindys(uint conv, OnlineExecWindyMode_v1_0_0 condition, string? sender)
{
- _ = Task.Run(async () =>
+ _ = Task.Run(async () =>
{
await Task.Delay(1500);
await InjectOnlineExecuteWindys(conv, condition, $"{sender}_AsyncTask");
@@ -203,47 +203,41 @@ static GameSessionDispatch()
{
if (Config.Global.EnableFullPacketLog)
{
- PacketLogger = new BaseLogger(new LoggerConfig(
- max_Output_Char_Count: 16 * 1024,
- use_Console_Wrapper: true,
- use_Working_Directory: true,
- global_Minimum_LogLevel: LogLevel.Information,
- console_Minimum_LogLevel: LogLevel.None,
- debug_LogWriter_AutoFlush: false,
- enable_Detailed_Time: true), new LogFileConfig
- {
- AutoFlushWriter = true,
- IsPipeSeparatedFile = true,
- MaximumLogLevel = LogLevel.Information,
- MinimumLogLevel = LogLevel.Information,
- FileIdentifier = "packet"
- });
+ var customconf = Log.GlobalConfig;
+ customconf.Global_Minimum_LogLevel = LogLevel.Information;
+ customconf.Console_Minimum_LogLevel = LogLevel.None;
+ PacketLogger = new BaseLogger(customconf, new LogFileConfig
+ {
+ AutoFlushWriter = true,
+ IsPipeSeparatedFile = true,
+ MaximumLogLevel = LogLevel.Information,
+ MinimumLogLevel = LogLevel.Information,
+ FileIdentifier = "packet",
+ AllowAutoFallback = true,
+ });
}
if (Config.Global.EnablePlayerStatLog)
{
- PlayerStatLogger = new BaseLogger(new LoggerConfig(
- max_Output_Char_Count: 16 * 1024,
- use_Console_Wrapper: true,
- use_Working_Directory: true,
+ var customconf = Log.GlobalConfig;
#if DEBUG
- global_Minimum_LogLevel: LogLevel.Debug,
+ customconf.Global_Minimum_LogLevel = LogLevel.Debug;
#else
- global_Minimum_LogLevel: LogLevel.Information,
+ customconf.Global_Minimum_LogLevel = LogLevel.Information;
#endif
- console_Minimum_LogLevel: LogLevel.None,
- debug_LogWriter_AutoFlush: false,
- enable_Detailed_Time: true), new LogFileConfig
- {
- AutoFlushWriter = true,
- IsPipeSeparatedFile = true,
- MaximumLogLevel = LogLevel.Error,
+ customconf.Console_Minimum_LogLevel = LogLevel.None;
+ PlayerStatLogger = new BaseLogger(customconf, new LogFileConfig
+ {
+ AutoFlushWriter = true,
+ IsPipeSeparatedFile = true,
+ MaximumLogLevel = LogLevel.Error,
#if DEBUG
- MinimumLogLevel = LogLevel.Debug,
+ MinimumLogLevel = LogLevel.Debug,
#else
- MinimumLogLevel = LogLevel.Information,
+ MinimumLogLevel = LogLevel.Information,
#endif
- FileIdentifier = "player.stat"
- });
+ FileIdentifier = "player.stat",
+ AllowAutoFallback = true,
+ });
PlayerStatLogger.Info($"UID|Status category|Description|--[Any other Data]--", "Conv ID");
}
@@ -266,7 +260,7 @@ from info in Config.Global.WindyConfig.OnlineExecWindys
///
/// Invoke the static initializer and create latest.packet.log and latest.player.stat.log.
///
- public static void InitializeLogFiles() { }
+ public static void InitializeLogFiles() { }
private static void AssertSessionExists(uint conv)
{
@@ -285,7 +279,7 @@ public static async Task ValidateWindyAutoExecute()
return;
foreach (var windyfile in from list in ExecuteWindyMap.Values
from item in list
- where item.OnlineExecMode != OnlineExecWindyMode_v1_0_0.Disabled
+ where item.OnlineExecMode != OnlineExecWindyMode_v1_0_0.Disabled
&& item.OnlineExecMode != OnlineExecWindyMode_v1_0_0.None
select item.LuaFileName)
{
diff --git a/csharp-Protoshift/KCP/KcpProxy/KcpProxyBase.cs b/csharp-Protoshift/KCP/KcpProxy/KcpProxyBase.cs
index b5ab44b10..6f5d312ce 100644
--- a/csharp-Protoshift/KCP/KcpProxy/KcpProxyBase.cs
+++ b/csharp-Protoshift/KCP/KcpProxy/KcpProxyBase.cs
@@ -1,6 +1,5 @@
-// #define KCP_PROXY_VERBOSE
+// #define KCP_PROXY_VERBOSE
-using csharp_Protoshift.GameSession;
using Newtonsoft.Json.Linq;
using System.Net;
using System.Net.Sockets;
diff --git a/csharp-Protoshift/KCP/KcpProxy/KcpProxyClient.cs b/csharp-Protoshift/KCP/KcpProxy/KcpProxyClient.cs
index f4c54660d..140cbbbbe 100644
--- a/csharp-Protoshift/KCP/KcpProxy/KcpProxyClient.cs
+++ b/csharp-Protoshift/KCP/KcpProxy/KcpProxyClient.cs
@@ -1,4 +1,4 @@
-using System.Diagnostics;
+using System.Diagnostics;
using System.Net;
namespace csharp_Protoshift.MhyKCP.Proxy
diff --git a/csharp-Protoshift/KCP/KcpProxy/KcpProxyServer.cs b/csharp-Protoshift/KCP/KcpProxy/KcpProxyServer.cs
index a94a03604..6fa3846ca 100644
--- a/csharp-Protoshift/KCP/KcpProxy/KcpProxyServer.cs
+++ b/csharp-Protoshift/KCP/KcpProxy/KcpProxyServer.cs
@@ -1,11 +1,10 @@
-// #define KCP_PROXY_VERBOSE // not avaliable currently
+// #define KCP_PROXY_VERBOSE // not avaliable currently
using System.Net;
using YYHEggEgg.Logger;
using csharp_Protoshift.SpecialUdp;
using System.Buffers.Binary;
using System.Net.Sockets.Kcp;
-using csharp_Protoshift.GameSession;
namespace csharp_Protoshift.MhyKCP.Proxy
{
@@ -17,18 +16,33 @@ public class KcpProxyServer : KCPServer
#if !PROTOSHIFT_BENCHMARK
static KcpProxyServer()
{
- _kcpstatlogger = new BaseLogger(new LoggerConfig(
- max_Output_Char_Count: 16 * 1024,
- use_Console_Wrapper: true,
- use_Working_Directory: true,
+#if !KCP_PERFORMANCE_TEST
+ if (BaseLogger.LogFileExists("player.stat"))
+ {
+#endif
+ var customconf = Log.GlobalConfig;
+#if DEBUG
+ customconf.Global_Minimum_LogLevel = LogLevel.Debug;
+#else
+ customconf.Global_Minimum_LogLevel = LogLevel.Information;
+#endif
+ customconf.Console_Minimum_LogLevel = LogLevel.None;
+ _kcpstatlogger = new BaseLogger(customconf, new LogFileConfig
+ {
+ AutoFlushWriter = true,
+ IsPipeSeparatedFile = true,
+ MaximumLogLevel = LogLevel.Error,
#if DEBUG
- global_Minimum_LogLevel: LogLevel.Debug,
+ MinimumLogLevel = LogLevel.Debug,
#else
- global_Minimum_LogLevel: LogLevel.Information,
+ MinimumLogLevel = LogLevel.Information,
+#endif
+ FileIdentifier = "player.stat",
+ AllowAutoFallback = true,
+ });
+#if !KCP_PERFORMANCE_TEST
+ }
#endif
- console_Minimum_LogLevel: LogLevel.None,
- debug_LogWriter_AutoFlush: false,
- enable_Detailed_Time: true), "player.stat");
}
#endif
@@ -89,9 +103,8 @@ protected override async Task BackgroundUpdate()
continue;
}
// ip dispatch
- string remoteIpString = packet.RemoteEndPoint.ToString();
KcpProxyBase conn;
- if (!connecting_clients.TryGetValue(remoteIpString, out var _outconn))
+ if (!connecting_clients.TryGetValue(packet.RemoteEndPoint, out var _outconn))
{
// Don't allow a disconnected session
if (removed_sessions.Contains(handshake.Conv))
@@ -102,9 +115,9 @@ protected override async Task BackgroundUpdate()
// Oh boy! A new connection!
conn = new KcpProxyBase(sendToAddress: SendToEndpoint);
conn.OutputCallback = new SocketUdpKcpCallback(udpSock, packet.RemoteEndPoint);
- Log.Dbug($"New connection established, remote endpoint={remoteIpString}");
+ Log.Dbug($"New connection established, remote endpoint={packet.RemoteEndPoint}", nameof(KcpProxyServer));
conn.AcceptNonblock();
- connecting_clients[remoteIpString] = conn;
+ connecting_clients[packet.RemoteEndPoint] = conn;
_ = Task.Run(async () =>
{
try
@@ -113,7 +126,7 @@ protected override async Task BackgroundUpdate()
}
catch
{
- connecting_clients.TryRemove(remoteIpString, out _);
+ connecting_clients.TryRemove(packet.RemoteEndPoint, out _);
}
});
}
diff --git a/csharp-Protoshift/KCP/MhyKCP/KCPClient.cs b/csharp-Protoshift/KCP/MhyKCP/KCPClient.cs
index 4cd0cdb61..49e477f6d 100644
--- a/csharp-Protoshift/KCP/MhyKCP/KCPClient.cs
+++ b/csharp-Protoshift/KCP/MhyKCP/KCPClient.cs
@@ -1,5 +1,6 @@
using System.Net;
using csharp_Protoshift.SpecialUdp;
+using YYHEggEgg.Logger;
namespace csharp_Protoshift.MhyKCP
{
diff --git a/csharp-Protoshift/KCP/MhyKCP/KCPServer.cs b/csharp-Protoshift/KCP/MhyKCP/KCPServer.cs
index cd5b356c6..5e6975a5c 100644
--- a/csharp-Protoshift/KCP/MhyKCP/KCPServer.cs
+++ b/csharp-Protoshift/KCP/MhyKCP/KCPServer.cs
@@ -12,8 +12,7 @@ public class KCPServer : IDisposable
protected SocketUdpClient udpSock;
protected bool _Closed = false;
- // string is the ToString() form of IPEndPoint
- protected ConcurrentDictionary connecting_clients;
+ protected ConcurrentDictionary connecting_clients;
protected ConcurrentDictionary connected_clients;
protected ConcurrentQueue newConnections;
protected ConcurrentBag removed_sessions;
@@ -83,9 +82,8 @@ protected virtual async Task BackgroundUpdate()
continue;
}
// ip dispatch
- string remoteIpString = packet.RemoteEndPoint.ToString();
MhyKcpBase conn;
- if (!connecting_clients.TryGetValue(remoteIpString, out var _outconn))
+ if (!connecting_clients.TryGetValue(packet.RemoteEndPoint, out var _outconn))
{
// Don't allow a disconnected session
if (removed_sessions.Contains(handshake.Conv)) continue;
@@ -93,7 +91,7 @@ protected virtual async Task BackgroundUpdate()
conn = new MhyKcpBase();
conn.OutputCallback = new SocketUdpKcpCallback(udpSock, packet.RemoteEndPoint);
conn.AcceptNonblock();
- connecting_clients[remoteIpString] = conn;
+ connecting_clients[packet.RemoteEndPoint] = conn;
_ = Task.Run(async () =>
{
try
@@ -102,7 +100,7 @@ protected virtual async Task BackgroundUpdate()
}
catch
{
- connecting_clients.TryRemove(remoteIpString, out _);
+ connecting_clients.TryRemove(packet.RemoteEndPoint, out _);
}
});
}
diff --git a/csharp-Protoshift/KCP/MhyKCP/KcpInnerBuffer.cs b/csharp-Protoshift/KCP/MhyKCP/KcpInnerBuffer.cs
index e1799eb12..20756fe95 100644
--- a/csharp-Protoshift/KCP/MhyKCP/KcpInnerBuffer.cs
+++ b/csharp-Protoshift/KCP/MhyKCP/KcpInnerBuffer.cs
@@ -1,4 +1,4 @@
-using System.Buffers;
+using System.Buffers;
namespace csharp_Protoshift.MhyKCP
{
diff --git a/csharp-Protoshift/KCP/MhyKCP/KcpPacketAudit.cs b/csharp-Protoshift/KCP/MhyKCP/KcpPacketAudit.cs
index eec4b3c34..9c3f1e2aa 100644
--- a/csharp-Protoshift/KCP/MhyKCP/KcpPacketAudit.cs
+++ b/csharp-Protoshift/KCP/MhyKCP/KcpPacketAudit.cs
@@ -1,9 +1,10 @@
-#define MIHOMO_KCP
+#define MIHOMO_KCP
using System.Buffers;
using System.Buffers.Binary;
using System.Collections.Concurrent;
using System.Diagnostics;
+using System.IO.Hashing;
using System.Net.Sockets.Kcp;
using System.Text;
using YYHEggEgg.Logger;
@@ -98,6 +99,10 @@ private static void BackgroundUpdate()
offset += sizeof(byte) + sizeof(ushort) + sizeof(uint) * 3;
uint len = BinaryPrimitives.ReadUInt32LittleEndian(segment.Slice(offset));
offset += sizeof(uint);
+#if BYTE_CHECK_MODE
+ uint byteCheckCode = BinaryPrimitives.ReadUInt32LittleEndian(segment.Slice(offset));
+ offset += sizeof(uint);
+#endif
Debug.Assert(offset == KcpConst.IKCP_OVERHEAD);
#endregion
#region Content Length Check
@@ -115,6 +120,16 @@ private static void BackgroundUpdate()
Convert.ToHexString(segment.Slice(
(int)(offset + len), (int)(contentLen - len))));
}
+#if BYTE_CHECK_MODE && !CORRUPT_PACKET
+ else
+ {
+ var checksum = Crc32.HashToUInt32(segment.Slice(offset));
+ if (byteCheckCode != checksum)
+ {
+ exceptions.Add($"Segment {i} byte check (CRC32) failed, expected: {byteCheckCode}, actual: {checksum}.");
+ }
+ }
+#endif
#endregion
}
}
@@ -149,7 +164,7 @@ private static void BackgroundUpdate()
#if MIHOMO_KCP
offset += sizeof(uint) * 2;
#else
- offset += sizeof(uint);
+ offset += sizeof(uint);
#endif
byte cmd = segment[offset];
offset += sizeof(byte);
@@ -165,6 +180,10 @@ private static void BackgroundUpdate()
offset += sizeof(uint);
uint len = BinaryPrimitives.ReadUInt32LittleEndian(segment.Slice(offset));
offset += sizeof(uint);
+#if BYTE_CHECK_MODE
+ uint byteCheckCode = BinaryPrimitives.ReadUInt32LittleEndian(segment.Slice(offset));
+ offset += sizeof(uint);
+#endif
Debug.Assert(offset == KcpConst.IKCP_OVERHEAD);
#endregion
#region Output segment
diff --git a/csharp-Protoshift/KCP/MhyKCP/MhyKcpBase.cs b/csharp-Protoshift/KCP/MhyKCP/MhyKcpBase.cs
index f4cf66463..ab530c3e2 100644
--- a/csharp-Protoshift/KCP/MhyKCP/MhyKcpBase.cs
+++ b/csharp-Protoshift/KCP/MhyKCP/MhyKcpBase.cs
@@ -1,4 +1,4 @@
-// #define KCP_INNER_LOG
+// #define KCP_INNER_LOG
// #define KCP_EXPORT_PACKET_RECORD
using System.Net.Sockets;
@@ -54,6 +54,11 @@ public enum ConnectionState
protected object cskcp_recvLock = "R.I.P YSFreedom";
protected object cskcp_sndLock = "Yolmiya";
protected long startTime;
+ ///
+ /// Used for assigning conv for new connections.
+ /// Use to operate with it.
+ ///
+ protected static uint _currentConv = 1000;
public uint ConnectData { get; protected set; }
public OuterCode.UniqueIDManager _uniqueID = new(nameof(MhyKcpBase));
@@ -75,6 +80,15 @@ public void Initialize()
cskcpHandle = new(_Conv, _Token, OutputCallback);
_State = ConnectionState.CONNECTED;
+#if BYTE_CHECK_MODE
+#if CORRUPT_PACKET
+ bool corrupt = true;
+#else
+ bool corrupt = false;
+#endif
+ cskcpHandle.SetByteCheck(2, corrupt);
+#endif
+
// Added
// IKCP.ikcp_nodelay(ikcpHandle, 1, 10, 2, 1);
// modified because mhy is using far more aggressive code, or 力大砖飞 mode
@@ -187,7 +201,7 @@ public virtual int Input(byte[] buffer)
{
// Log.Dbug($"HandShakeWaitNotify, buf = {Convert.ToHexString(buffer)}", nameof(MhyKcpBase));
handshake.Decode(buffer, Handshake.MAGIC_CONNECT);
- _Conv = (uint)(MonotonicTime.Now & 0xFFFFFFFF);
+ _Conv = Interlocked.Increment(ref _currentConv);
_Token = 0xFFCCEEBB ^ (uint)((MonotonicTime.Now >> 32) & 0xFFFFFFFF);
var sendBackConv = new Handshake(Handshake.MAGIC_SEND_BACK_CONV, _Conv, _Token).AsBytes();
diff --git a/csharp-Protoshift/KCP/MhyKCP/UdpKcpCallback.cs b/csharp-Protoshift/KCP/MhyKCP/UdpKcpCallback.cs
index 73b8fd9cc..a234190a9 100644
--- a/csharp-Protoshift/KCP/MhyKCP/UdpKcpCallback.cs
+++ b/csharp-Protoshift/KCP/MhyKCP/UdpKcpCallback.cs
@@ -1,10 +1,12 @@
-#define KCP_PACKET_AUDIT
+// #define KCP_PACKET_AUDIT
using csharp_Protoshift.SpecialUdp;
using System.Buffers;
+using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Net.Sockets.Kcp;
+using YYHEggEgg.Logger;
namespace csharp_Protoshift.MhyKCP
{
@@ -42,11 +44,15 @@ public SocketUdpKcpCallback(SocketUdpClient udpSock, IPEndPoint? ipEp = null)
public void Output(IMemoryOwner buffer, int avalidLength, bool isKcpPacket = true)
{
// Stopwatch udpwatch = Stopwatch.StartNew();
- // DateTime req_SendTime = DateTime.Now;
+#if KCP_PACKET_AUDIT
+ DateTime req_SendTime = DateTime.Now;
+#endif
// udpSock.SendToAsync(buffer.Memory.Slice(0, avalidLength), ipEp).Wait();
udpSock.SendTo(buffer.Memory.Span.Slice(0, avalidLength), ipEp);
- // if (isKcpPacket)
- // KcpPacketAudit.PushPacket(req_SendTime, buffer.Memory, avalidLength);
+#if KCP_PACKET_AUDIT
+ if (isKcpPacket)
+ KcpPacketAudit.PushPacket(req_SendTime, buffer.Memory, avalidLength);
+#endif
buffer.Dispose();
// udpwatch.Stop();
// Log.Dbug($"SocketUdpKcpCallback output elapsed {udpwatch.Elapsed.TotalMilliseconds}ms.");
diff --git a/csharp-Protoshift/KCP/SingleThreadAssert.cs b/csharp-Protoshift/KCP/SingleThreadAssert.cs
index a598246d3..15037ea68 100644
--- a/csharp-Protoshift/KCP/SingleThreadAssert.cs
+++ b/csharp-Protoshift/KCP/SingleThreadAssert.cs
@@ -1,4 +1,5 @@
-using YYHEggEgg.Logger;
+using YYHEggEgg.Logger;
+
namespace csharp_Protoshift
{
///
diff --git a/csharp-Protoshift/KCP/SpecialUdp/SocketUdpClient.cs b/csharp-Protoshift/KCP/SpecialUdp/SocketUdpClient.cs
index ed84821c6..2e8dfc862 100644
--- a/csharp-Protoshift/KCP/SpecialUdp/SocketUdpClient.cs
+++ b/csharp-Protoshift/KCP/SpecialUdp/SocketUdpClient.cs
@@ -1,4 +1,4 @@
-// #define SOCKET_UDP_VERBOSE
+// #define SOCKET_UDP_VERBOSE
// #define SOCKET_UDP_PACKET_CONTENT_VERBOSE
// #define SOCKET_UDP_PACKET_CONTENT_VERBOSE_SYNCRONOUS
@@ -175,7 +175,7 @@ public async Task ReceiveFromAsync()
var stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
#endif
-
+
var result = await _socket.ReceiveFromAsync(buffer, SocketFlags.None,
receiveResult.RemoteEndPoint);
@@ -441,7 +441,6 @@ public void Close()
public class SocketUdpReceiveResult
{
-
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public byte[] Buffer;
public int ReceivedBytes;
diff --git a/csharp-Protoshift/LoggerChannelTraceExtensions.cs b/csharp-Protoshift/LoggerChannelTraceExtensions.cs
deleted file mode 100644
index 3df39a306..000000000
--- a/csharp-Protoshift/LoggerChannelTraceExtensions.cs
+++ /dev/null
@@ -1,328 +0,0 @@
-using YYHEggEgg.Logger;
-
-namespace csharp_Protoshift
-{
- public static class LoggerChannelTraceExtensions
- {
- private static object _exception_lck = "<3 from miHomo Technology";
- private static Dictionary _trace_ids = new();
- private static int _total_characters = 0;
- private const int MAXIMUM_MEMORY_CHARS = 4 * 1024 * 1024; // >= 4MB
- private static bool _initialized = false;
- private static BaseLogger? _tracelog;
-
- private static void Initialize()
- {
- lock (_exception_lck)
- {
- if (_initialized) return;
-
- _tracelog = new BaseLogger(new LoggerConfig(
- max_Output_Char_Count: Log.GlobalConfig.Max_Output_Char_Count,
- use_Console_Wrapper: Log.GlobalConfig.Use_Console_Wrapper,
- use_Working_Directory: Log.GlobalConfig.Use_Working_Directory,
- global_Minimum_LogLevel: LogLevel.Information,
- console_Minimum_LogLevel: LogLevel.None,
- debug_LogWriter_AutoFlush: true,
- is_PipeSeparated_Format: false,
- enable_Detailed_Time: Log.GlobalConfig.Enable_Detailed_Time
- ), new LogFileConfig
- {
- MinimumLogLevel = LogLevel.Information,
- MaximumLogLevel = LogLevel.Information,
- AutoFlushWriter = true,
- FileIdentifier = "errtrace",
- IsPipeSeparatedFile = false,
- });
-
- _initialized = true;
- }
- }
-
- private static (Guid traceid, bool isnew) AssignTraceId(string ex_full_content)
- {
- (Guid traceid, bool isnew) rtn;
- lock (_exception_lck)
- {
- if (!_trace_ids.TryGetValue(ex_full_content, out Guid id))
- {
- rtn = (Guid.NewGuid(), true);
- _trace_ids.Add(ex_full_content, rtn.traceid);
- return rtn;
- }
-
- _total_characters += ex_full_content.Length;
- if (_total_characters > MAXIMUM_MEMORY_CHARS)
- {
- var tmp = _trace_ids[ex_full_content];
- _trace_ids.Clear();
- _trace_ids.Add(ex_full_content, tmp);
- }
- rtn = (id, false);
- return rtn;
- }
- }
-
- ///
- /// 以 将
- /// 与 输出至 ,
- /// 并将额外的异常堆栈跟踪信息输出到 latest.errtrace.log.
- ///
- /// 程序中发生的异常信息。
- /// 需要在控制台中输出的错误发生地点摘要。
- /// 查询或分配的 Trace ID.
- public static Guid LogExceptionTrace(this LoggerChannel logger,
- Exception? ex, LogLevel logLevel, string? prompt = null)
- {
- Initialize();
- var traceinfo = ex?.ToString() ?? string.Empty;
- var extype = ex?.GetType().ToString() ?? "";
- var exmsg = ex?.Message ?? "";
- (Guid traceid, bool isnew) = AssignTraceId(traceinfo);
-
- logger.LogPush($"{prompt}{extype}: {exmsg} (Trace ID: {traceid})",
- logLevel);
- if (isnew) _tracelog?.Info($"Trace ID [{traceid}]: \n{traceinfo}", logger.LogSender);
- return traceid;
- }
-
- ///
- /// Output with
- /// to ,
- /// and output the extra detailed exception trace to
- /// latest.errtrace.log.
- ///
- /// The exception caught in the program.
- /// The summary of where the exception is caught.
- /// 查询或分配的 Trace ID.
- public static Guid LogErroTrace(this LoggerChannel logger,
- Exception? ex, string? prompt = null)
- => LogExceptionTrace(logger, ex, LogLevel.Error, prompt);
-
- ///
- /// Output with
- /// to ,
- /// and output the extra detailed exception trace to
- /// latest.errtrace.log.
- ///
- /// The exception caught in the program.
- /// The summary of where the exception is caught.
- /// 查询或分配的 Trace ID.
- public static Guid LogWarnTrace(this LoggerChannel logger,
- Exception? ex, string? prompt = null)
- => LogExceptionTrace(logger, ex, LogLevel.Warning, prompt);
-
- ///
- /// Output with
- /// to ,
- /// and output the extra detailed exception trace to
- /// latest.errtrace.log.
- ///
- /// The exception caught in the program.
- /// The summary of where the exception is caught.
- /// 查询或分配的 Trace ID.
- public static Guid LogInfoTrace(this LoggerChannel logger,
- Exception? ex, string? prompt = null)
- => LogExceptionTrace(logger, ex, LogLevel.Information, prompt);
-
- ///
- /// Output with
- /// to ,
- /// and output the extra detailed exception trace to
- /// latest.errtrace.log.
- ///
- /// The exception caught in the program.
- /// The summary of where the exception is caught.
- /// 查询或分配的 Trace ID.
- public static Guid LogDbugTrace(this LoggerChannel logger,
- Exception? ex, string? prompt = null)
- => LogExceptionTrace(logger, ex, LogLevel.Debug, prompt);
-
- ///
- /// Output with
- /// to ,
- /// and output the extra detailed exception trace to
- /// latest.errtrace.log.
- ///
- /// The exception caught in the program.
- /// The summary of where the exception is caught.
- /// 查询或分配的 Trace ID.
- public static Guid LogVerbTrace(this LoggerChannel logger,
- Exception? ex, string? prompt = null)
- => LogExceptionTrace(logger, ex, LogLevel.Verbose, prompt);
- }
-
- public static class BaseLoggerTraceExtensions
- {
- ///
- /// Output with
- /// a given to the global main logger,
- /// and output the extra detailed exception trace to
- /// latest.errtrace.log.
- ///
- /// The exception caught in the program.
- /// The summary of where the exception is caught.
- /// The sender param used by logging.
- /// 查询或分配的 Trace ID.
- public static Guid ExceptionTrace(this BaseLogger logger,
- Exception? ex, LogLevel logLevel, string? sender = null, string? prompt = null)
- => logger.GetChannel(sender).LogExceptionTrace(ex, logLevel, prompt);
-
- ///
- /// Output with
- /// to the global main logger,
- /// and output the extra detailed exception trace to
- /// latest.errtrace.log.
- ///
- /// The exception caught in the program.
- /// The summary of where the exception is caught.
- /// The sender param used by logging.
- /// 查询或分配的 Trace ID.
- public static Guid ErroTrace(this BaseLogger logger,
- Exception? ex, string? sender = null, string? prompt = null)
- => logger.GetChannel(sender).LogErroTrace(ex, prompt);
-
- ///
- /// Output with
- /// to the global main logger,
- /// and output the extra detailed exception trace to
- /// latest.errtrace.log.
- ///
- /// The exception caught in the program.
- /// The summary of where the exception is caught.
- /// The sender param used by logging.
- /// 查询或分配的 Trace ID.
- public static Guid WarnTrace(this BaseLogger logger,
- Exception? ex, string? sender = null, string? prompt = null)
- => logger.GetChannel(sender).LogWarnTrace(ex, prompt);
-
- ///
- /// Output with
- /// to the global main logger,
- /// and output the extra detailed exception trace to
- /// latest.errtrace.log.
- ///
- /// The exception caught in the program.
- /// The summary of where the exception is caught.
- /// The sender param used by logging.
- /// 查询或分配的 Trace ID.
- public static Guid InfoTrace(this BaseLogger logger,
- Exception? ex, string? sender = null, string? prompt = null)
- => logger.GetChannel(sender).LogInfoTrace(ex, prompt);
-
- ///
- /// Output with
- /// to the global main logger,
- /// and output the extra detailed exception trace to
- /// latest.errtrace.log.
- ///
- /// The exception caught in the program.
- /// The summary of where the exception is caught.
- /// The sender param used by logging.
- /// 查询或分配的 Trace ID.
- public static Guid DbugTrace(this BaseLogger logger,
- Exception? ex, string? sender = null, string? prompt = null)
- => logger.GetChannel(sender).LogDbugTrace(ex, prompt);
-
- ///
- /// Output with
- /// to the global main logger,
- /// and output the extra detailed exception trace to
- /// latest.errtrace.log.
- ///
- /// The exception caught in the program.
- /// The summary of where the exception is caught.
- /// The sender param used by logging.
- /// 查询或分配的 Trace ID.
- public static Guid VerbTrace(this BaseLogger logger,
- Exception? ex, string? sender = null, string? prompt = null)
- => logger.GetChannel(sender).LogVerbTrace(ex, prompt);
- }
-
- public static class LogTrace
- {
- ///
- /// Output with
- /// a given to the global main logger,
- /// and output the extra detailed exception trace to
- /// latest.errtrace.log.
- ///
- /// The exception caught in the program.
- /// The summary of where the exception is caught.
- /// The sender param used by logging.
- /// 查询或分配的 Trace ID.
- public static Guid ExceptionTrace(
- Exception? ex, LogLevel logLevel, string? sender = null, string? prompt = null)
- => Log.GlobalBasedLogger.ExceptionTrace(ex, logLevel, sender, prompt);
-
- ///
- /// Output with
- /// to the global main logger,
- /// and output the extra detailed exception trace to
- /// latest.errtrace.log.
- ///
- /// The exception caught in the program.
- /// The summary of where the exception is caught.
- /// The sender param used by logging.
- /// 查询或分配的 Trace ID.
- public static Guid ErroTrace(
- Exception? ex, string? sender = null, string? prompt = null)
- => Log.GlobalBasedLogger.ErroTrace(ex, sender, prompt);
-
- ///
- /// Output with
- /// to the global main logger,
- /// and output the extra detailed exception trace to
- /// latest.errtrace.log.
- ///
- /// The exception caught in the program.
- /// The summary of where the exception is caught.
- /// The sender param used by logging.
- /// 查询或分配的 Trace ID.
- public static Guid WarnTrace(
- Exception? ex, string? sender = null, string? prompt = null)
- => Log.GlobalBasedLogger.WarnTrace(ex, sender, prompt);
-
- ///
- /// Output with
- /// to the global main logger,
- /// and output the extra detailed exception trace to
- /// latest.errtrace.log.
- ///
- /// The exception caught in the program.
- /// The summary of where the exception is caught.
- /// The sender param used by logging.
- /// 查询或分配的 Trace ID.
- public static Guid InfoTrace(
- Exception? ex, string? sender = null, string? prompt = null)
- => Log.GlobalBasedLogger.InfoTrace(ex, sender, prompt);
-
- ///
- /// Output with
- /// to the global main logger,
- /// and output the extra detailed exception trace to
- /// latest.errtrace.log.
- ///
- /// The exception caught in the program.
- /// The summary of where the exception is caught.
- /// The sender param used by logging.
- /// 查询或分配的 Trace ID.
- public static Guid DbugTrace(
- Exception? ex, string? sender = null, string? prompt = null)
- => Log.GlobalBasedLogger.DbugTrace(ex, sender, prompt);
-
- ///
- /// Output with
- /// to the global main logger,
- /// and output the extra detailed exception trace to
- /// latest.errtrace.log.
- ///
- /// The exception caught in the program.
- /// The summary of where the exception is caught.
- /// The sender param used by logging.
- /// 查询或分配的 Trace ID.
- public static Guid VerbTrace(
- Exception? ex, string? sender = null, string? prompt = null)
- => Log.GlobalBasedLogger.VerbTrace(ex, sender, prompt);
- }
-}
\ No newline at end of file
diff --git a/csharp-Protoshift/csharp-Protoshift.csproj b/csharp-Protoshift/csharp-Protoshift.csproj
index 12e227f99..6764402c3 100644
--- a/csharp-Protoshift/csharp-Protoshift.csproj
+++ b/csharp-Protoshift/csharp-Protoshift.csproj
@@ -28,7 +28,7 @@
-
+