# packet\_manipulator\_simple

## packet\_manipulator\_simple サンプル

<figure><img src="https://669307705-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlFJ89PMX2ike3NyauXNM%2Fuploads%2FYpFWmmyOo2Ke9UwnWtOc%2Fimage.png?alt=media&#x26;token=f369d1cc-8e99-48b1-9a19-4cf050c10880" alt=""><figcaption></figcaption></figure>

### 概要

packet\_manipulator\_simple サンプルは Packet Manipulator の基本的な使用方法とプリセットフィルタの設定方法のサンプルとなっています。\
サンプルコードでは Packet Manipulator の実装コードのフォーカスしているため、Diarkis Runtime の基本的な実装については関数化して説明等は記載していません。 Diarkis Runtime の基本的な実装について知りたい場合は [room\_broadcast サンプル](https://help.diarkis.io/diarkis-client/samples/cpp/broken-reference) や [Diarkis モジュール利用の全体的な流れ](https://help.diarkis.io/diarkis-module#diarkis-module-noi) を参照してください。\
また、Packet Manipulator 全般については [Packet Manipulator ](https://help.diarkis.io/diarkis-client/runtime-library/packet-manipulator)を参照してください。

**本サンプルはデバッグ機能のサンプル実装のため Release ビルドはできません。**

### ローカル環境でサーバーを起動する

サンプルで使用するサーバーを起動するためのチュートリアルを実施して、ローカル環境で Diarkis サーバーを起動します。

[Diarkis サーバをローカルで起動する](https://help.diarkis.io/getting-started/tutorial/setup-local-server)

### サンプルの引数

サンプルの起動時には以下の３つのパラメータを指定してください。

`packet_manipulator_simple.exe serverAddr UID clientKey`

| 引数         | 説明                            |
| ---------- | ----------------------------- |
| serverAddr | Diarkis サーバのエンドポイントを指定してください  |
| UID        | 接続するユーザーの ID を任意の文字列で指定してください |
| clientKey  | クライアントキーを任意の文字列で指定してください      |

#### 起動例：

`packet_manipulator_simple.exe 192.168.1.123:7000 1111 AAAA`

### 起動方法

本サンプルは起動すると Room に接続し、Room のメンバー数が 2 人になるまで待機します。 2 ユーザーが Room に接続後、Packet Manipulator のフィルタ設定を変えながら通信を行いフィルタ適用の結果を画面に表示します。

## packet\_manipulator\_simple サンプル解説

本セクションではサンプルの実装ポイントについて解説します。

### Packet Manipulator の更新処理実装

Packet Manipulator では内部状態を更新するために定期的に `IPacketManipulator::Update` を実行する必要があります。\
本サンプルではこの処理を専用スレッドを用意して実装しています。具体的には `LaunchPacketManipulatorThread` で専用スレッドを起動し、`ManipulatorLoop` で `IPacketManipulator::Update` を実行しています。 サンプルのコメントにもありますように、この処理の実行頻度が Packet Filter の実行間隔となり、Packet Filter の機能にも影響します。本サンプルではパケット遅延フィルタを利用しており、なるべく遅延の値がぶれないように 30 ms 間隔で `IPacketManipulator::Update` を呼び出すようにしています。\
更新処理に専用スレッドを用意することは必須というわけではなく、ゲームのループで毎フレーム実行するような形でも問題ありません。

### プロファイル情報の表示

本サンプルでは `FilterApplyPoint::RawUdpReceive` へ Packet Filter を適用しています。この Apply Point は Diarkis の UDP 通信すべてに影響する Apply Point で、この Apply Point でパケロスや遅延が発生すると Diarkis のプロファイル情報にも影響するようになっています。本サンプルでは Packet Filter の影響をわかりやすくするためこのプロファイル情報を利用しています。

### Packet Manipulator の利用方法の解説

1. `DiarkisGetPacketManipulator` を使用して Packet Manipulator のインスタンスを Diarkis Runtime から取得します。

```
// Get Packet Manipulator pointer from the runtime.
// You can access the all features of the Packet Manipulator from here.
auto pacman = Diarkis::System::PacketManipulator::DiarkisGetPacketManipulator();
```

2. `IPacketManipulator::GetOrAllocFilterSet` を使用して `FilterApplyPoint::RawUdpReceive` Apply Point の `IFilterSet` を取得します。

```
// Get a filter set for Raw UDP Receive packets.
// Packet Manipulator works by applying filters in the filter set for a specific apply point.
// In this sample, we use the Raw UDP Receive filter set to apply the filters to incoming raw UDP packets in the Diarkis runtime.
auto rawUdpRecvFilterSet = pacman->GetOrAllocFilterSet(Diarkis::System::PacketManipulator::FilterApplyPoint::RawUdpReceive);
```

3. `IFilterSet` は `std::weak_ptr` で返されるため、使用する前に有効性をチェックしてください。\
   また、Filter Set と Apply Point に互換性がない場合は nullptr が返りますのでご注意ください。　　 本サンプルでは `IFilterSet` のポインタを取得後、プリセットのパケロスフィルターを設定しています。

```
if (auto rawUdpRecvFilterSetPtr = rawUdpRecvFilterSet.lock())
{
    // You can specify the packet loss rate (probability) when adding the filter.
    // You can also set a seed value for random number generation.
    // This filter uses the pseudo-random number generator to decide whether to drop a packet or not based on the specified probability.
    // Basically, the order of packet loss is always the same when you use the same seed value.
    // But the order of the incoming packets will be different in different network conditions, so the actual lost packets may differ, even with the same seed.
    rawUdpRecvFilterSetPtr->AddPacketLossFilter(packetLossProbability, 12345);
}
```

4. `FilterApplyPoint::RawUdpReceive` は Diarkis が扱うすべての UDP パケットに対して適用されます。本サンプルでは Room と P2P でパケットを送信してプロファイルのパケロス率に影響していることを確認できます。
5. 以下、パケットの遅延と複数 Packet Filter 適用のサンプル実装となっていますが、基本的な構造はここまでの流れと同じです。
