オンラインの入植者のためのボットの例のAMFとC#

Settlersに関する投稿を読んで、特にSettlers Onlineのユーティリティを書いた後、そこに記述されているプロセスをいくらか最適化したいという要望がありました。 このアプローチは私を多少混乱させ、同時に、C#のamf形式の側面を考慮します。 このゲームのボットを作成するタスクが選択されているとします。



まず、ログイン手順を処理する必要があります。





まず、ツールを決定しましょう。



1. チャールズ -amfメッセージ形式をサポートするデバッグプロキシ(試用版は長いナグスクリーンで迷惑で、30分ごとにオフになります)。

2. Fiddlerはプロキシでもあり、 httpsトラフィックをよりよく処理します (無料)。

3.フラッシュドライブ自体を表示するもの。ここに選択肢があります。

-AS3 Sorcerer-高速で簡単、フラッシュプロテクターにうまく対応します(試用版があり、時々面白い写真でナグ画面を表示します)。

- 多数SWF Decrypt (無料)+任意のフラッシュデコンパイラ、たとえばhttp://www.sothink.com/ (試用版では機能が切り捨てられていますが、これで十分です)。

4. FluorineFx -amf0およびamf3形式をサポートするオープンソースフレームワーク。



必要なものをすべて用意して、ゲームログインの段階の分析を開始できます。



1. httpsを使用してhttps://www.diesiedleronline.de/de/api/user/loginに直接ログインします

2.「Big Brother」サービスhttp://bb.diesiedleronline.de/を使用して、チャットサーバーでセッションキーとパスワードを取得する

3.最初のパッケージはすでにゲームのメインゲートウェイにあります。



順番に始めましょう。ログイン時に何が送信されるかを見るために、Fiddlerを実行し、設定でhttpsトラフィックを開いてゲームにログインしましょう。





あなたがこれを知っていると仮定して、httpリクエストなどの基本的なことをどのように行うかを書き留めません。 証明書の検証の瞬間を処理する必要があるという唯一の注意は、次のコードを追加するのに十分です。

  1. System. Net . ServicePointManager . ServerCertificateValidationCallback = delegate ( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors ) { return true ; } ;



  2. System. Net . ServicePointManager . ServerCertificateValidationCallback = delegate ( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors ) { return true ; } ;



  3. System. Net . ServicePointManager . ServerCertificateValidationCallback = delegate ( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors ) { return true ; } ;



  4. System. Net . ServicePointManager . ServerCertificateValidationCallback = delegate ( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors ) { return true ; } ;



  5. System. Net . ServicePointManager . ServerCertificateValidationCallback = delegate ( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors ) { return true ; } ;



  6. System. Net . ServicePointManager . ServerCertificateValidationCallback = delegate ( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors ) { return true ; } ;



  7. System. Net . ServicePointManager . ServerCertificateValidationCallback = delegate ( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors ) { return true ; } ;



  8. System. Net . ServicePointManager . ServerCertificateValidationCallback = delegate ( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors ) { return true ; } ;







同様に、ビッグブラザーに行くものをのぞき見します。 ゲートウェイアドレス、チャットサーバーキーを取得します。



そして、ここからが楽しみです。クライアントから送信されるパケットは非常に見えますが、サーバーの応答は解析されません。 このため、元のフラッシュドライブコードを覗くことができれば便利ですが、それについては後で詳しく説明します。



Fluorinefx





ゲームはFlexを使用して作成されたため、amf3メッセージ形式を使用します。 サーバーに接続するには、ゲートウェイアドレス(BBから取得)、サーバーで作動する関数の名前、パラメーター自体が必要です。

そこで、ゲームを開始し、Charlesを開き、発信パッケージの形式を確認します



dataObjectに追加のパラメーターを含むdServerCallオブジェクトは整数型であることがわかりました。

OK、すべてがシンプルで、クラスをすばやくスケッチして、非常に基本的なことを見つけます...

FluorineFx-素晴らしいライブラリは、基本的なものを除き、私たち全員に適しています-クラス名とそのフィールドのマッピング(マッチング)。 少しパッチを適用する必要があります。これには独自の属性があります

  1. [ AttributeUsage AttributeTargets。 プロパティ | AttributeTargets。Class ]
  2. パブリック クラス AmfObjectName System属性
  3. {
  4. public const string DefaultPrefix = "defaultGame.Communication.VO。" ;
  5. パブリック ストリング Name { get ; セット; }
  6. パブリック AmfObjectName 文字列
  7. {
  8. 名前=名前;
  9. }
  10. }


これを使用して、ボットとサーバー上のオブジェクトの名前とそのプロパティを一致させます。

ライブラリを販売した後、WriteAMF3Objectメソッド(flexを使用するため、amf3形式のみを使用することを忘れないでください)およびGetMemberでIO.AMFWriterに属性チェックを挿入する必要があることを理解できます。 簡単にわかります
  1. if IsClassAttributed type
  2. {
  3. propertyInfo = FindProperty type、member。Name ;
  4. }


どこで

  1. public static bool IsClassAttributed タイプtype
  2. {
  3. var res = type。 GetCustomAttributes typeof AmfObjectName false ;
  4. nullを 返し ます != res && res。 長さ > 0 ;
  5. }
  6. public static PropertyInfo FindProperty タイプタイプ、 文字列 amfObjName
  7. {
  8. foreach var prop in type。GetProperties
  9. {
  10. var attrs = prop。 GetCustomAttributes typeof AmfObjectName false ;
  11. if null == attrs || 0 == attrs。 長さ || AmfObjectName attrs [ 0 ] Name != amfObjName
  12. {
  13. 続ける;
  14. }
  15. リターンプロップ;
  16. }
  17. nullを返します
  18. }




同様に、AMFReaderを編集します。 もちろん、検出されたプロパティの基本的なキャッシュを構成する必要があります。実際、このプロセスについては説明しません。すべてが単純であるためです。

さらに、インスタンスを作成するためのデータの逆シリアル化を作成するときにクラスを表示するには、それらをフッ素キャッシュに「登録」する必要があります。 これを行うには、ObjectFactoryクラスを探してメソッドを追加します



  1. public static void AddToLocate type type、 string mapName
  2. {
  3. _typeCache。 追加 mapName、type ;
  4. }




アプリケーションの開始時に、すべてのクラスを登録します



  1. foreach Assemblyのvar型。GetExecutingAssembly GetTypes
  2. {
  3. var attrs = type。 GetCustomAttributes typeof AmfObjectName false ;
  4. if null == attrs || 0 == attrs。 長さ
  5. {
  6. 続ける;
  7. }
  8. ObjectFactory。 AddToLocate type、AmfObjectName。DefaultPrefix + AmfObjectName attrs [ 0 ] Name ;
  9. }




ところで、AmfObjectName.DefaultPrefixは、すべてのクラスの属性に同じことを書き込まないように巻き上げられています:)



それでは、クラスを説明します。



  1. 名前空間 SettlersControl。 オブジェクト
  2. {
  3. [ AmfObjectName "dServerCall" ]
  4. パブリック クラス SettlerRequest
  5. {
  6. public static int PlayerZoneId = 0 ;
  7. [ AmfObjectName "type" ]
  8. public int Type { get ; セット; }
  9. [ AmfObjectName "zoneID" ]
  10. public int ZoneId { get ; セット; }
  11. [ AmfObjectName "dataObject" ]
  12. パブリック オブジェクト DataObject { get ; セット; }
  13. public SettlerRequest SettlerMessagesメッセージ、 オブジェクト dataObject
  14. {
  15. タイプ= int メッセージ;
  16. ZoneID = PlayerZoneId ;
  17. DataObject = dataObject ;
  18. }
  19. }
  20. }




すべてがデータと分析の最初の送信の準備ができており、実際にチャールズは解析に対処する必要があります。 ライブラリからサンプルを開き、make、runを実行し、...応答で例外のみを取得します。 明らかに、チャーリーが落ちたのも不思議ではありません。 わかりましたが、原因はdUniqueIDです。 例外から判断すると、IExternalizable要素は処理できません。 Googleにアクセスすると、これはユーザーがオブジェクトを自分でシリアル化できる特定の形式であることがわかります。 これが最初の問題です。 オブジェクトの形式とそのフィールドの記録順序がわからないので、私たちにとって何も輝いていません。 したがって、開発者がそこで行ったことをスパイする機会は私たちにとって有益です。 Sorcererを開き、USBフラッシュドライブに設定し、目的のファイルを探して必要なデータを確認します



素晴らしい、フッ素開発者によって慎重に提供されたインターフェースを使用してこれを実装することは残っています:

  1. [ AmfObjectName "dUniqueID" ]
  2. パブリック クラス SettlerUniqueId IExternalizable
  3. {
  4. [ AmfObjectName "uniqueID1" ]
  5. public int UniqueID1 { get ; セット; }
  6. [ AmfObjectName "uniqueID2" ]
  7. public int UniqueID2 { get ; セット; }
  8. public void ReadExternal IDataInput入力
  9. {
  10. UniqueID1 =入力。 ReadInt ;
  11. UniqueID2 =入力。 ReadInt ;
  12. }
  13. public void WriteExternal IDataOutput出力
  14. {
  15. 出力。 WriteInt UniqueID1 ;
  16. 出力。 WriteInt UniqueID2 ;
  17. }
  18. }




類推により、必要なクラスを作成し、エラーを克服し、最後に最初のデータを受信します。



これは非常に始まりであることは明らかですが、主な問題は常に最初にあります:)

希望する人がいれば、ボットを書いて結果をアップロードし続けます。



All Articles