サーバー側で十分な計算時間がある場合は、さまざまなパッケージ タイプのプロトタイプを作成する手法に取り組む必要があります。
このポイントとアイデアを説明するために、UML のようなクラスの説明をいくつか示します。
UML:
class PacketPrototype
+ PacketPrototype(PacketType)
+ addData(DataType, Bitlength, ...)
+ deserilize(Bitstream stream) : ReceivedPacket
+ serilizeThis() : ToSendPacket
+ getPacketType() : int
また、すべての PacketPrototypes を持ち、各 PacketPrototype オブジェクトの Type を決定するクラスも必要です。どの Prototype を使用してデータをデシリアライズする必要がありますか。
すべての PacketPrototype を認識する 1 つのクラスが必要です。私はそれを PacketPrototypeHolder と呼んでいます
class PacketPrototypeHolder
+ register(PacketPrototype)
+ getPrototypeForPacketType(int Type) : PacketPrototype
セットアップ時のプロトコルは次のとおりです。
PacketEnemy00 = new PacketPrototype(0)
PacketEnemy00.addData(Types.Int, 5) // health
PacketEnemy00.addData(Types.String, 16) // name
...
これは、タイプ 0 のパケットが 5 ビット長の int と最大長 16 文字の文字列から構成されることを意味します。
セットアップ後に PacketPrototype を PacketPrototypeHolder に追加する必要があります。
PacketHolder.register(PacketEnemy00)
サーバーまたはクライアントがパケットのタイプを読み取る何かを受信した場合、それを行います ( Bitstreamからデータを読み取ることができます)
Type = Bitstream.readInt(5)
Prototype = PacketHolder.getPrototypeForPacketType(Type)
ReceivedPacket OfReceivedPacket = Prototype.deserilize(Bitstream)
// we need here a switch/if statement to determine how to handle the reading of the data
switch(Type)
{
case 0: // PacketEnemy00
呼び出しはデータストリームからデータを読み取り、Prototype.deserilize
それを ReceivedPacket オブジェクトに入れます。そこから、インデックス操作または名前付きアクセスを使用してデータにアクセスできます。
例として、私はインデックスでそれを行います
int UnitHealth = OfReceivedPacket.getInt(/* index, we want the 1st int */0);
string UnitName = OfReceivedPacket.getString(/* index, we want the 1st string */0);
and so on...
break;
...
}
そのため、switch ステートメントをネットワーク レイヤー内からアプリケーション/使用レイヤーに効果的に移動しました。
スイッチを削除するには、データ駆動型のアプローチが必要です。しかし、ハードコードされたアプローチよりも実現するのがエンジンの方が複雑です。