public void EnqueueOnConnect(string connectionId, string token) { XrossPeer.TimeAssert(Develop.TIME_ASSERT, "connectionIdとplayerDataが揃った状態でくる。ので、ここで照会を行ってしまおう。token:" + token); var playerId = token; XrossPeer.Log("playerId:" + playerId + " connectionId:" + connectionId); // set connectionId to reserved playerId. var succeeded = gameLayer.SetConnectionIdOfPlayerId(playerId, connectionId); if (!succeeded) { return; } if (playerId == "_empty_") { XrossPeer.Log("接続時にプレイヤーIDが空のユーザーが接続してきた。追い返すようにしてある。"); return; } var data = new Commands.OnConnected(playerId).ToData(); if (true) { gameLayer.EnqueOnReceive(connectionId, data); } }
public void EnqueueOnMessage(string connectionId, byte[] data) { XrossPeer.TimeAssert(Develop.TIME_ASSERT, "とりあえずすべてのconnectionIdに対して、このreserveレイヤに登録があった、みたいなみなしをしてうけいれる。実際にはReservationLayerが複数のGameLayerをもっていて、特定の情報を元にGameContextLayerへとメッセージをふり分ける。"); if (true) { gameLayer.EnqueOnReceive(connectionId, data); } }
/** * main loop of GameContext. */ public bool UpdateGameLayer() { switch (state) { case BattleState.STATE_READY: { XrossPeer.TimeAssert(Develop.TIME_ASSERT, "絶賛準備中のステート、2フレームくらい回してみよう。clientのリトライを試す、、のはあとで。"); if (true) { XrossPeer.TimeAssert(Develop.TIME_ASSERT, "Server起動中、準備中など。いろんなConnectionとかロードが完了したらプレイヤーがいない世界へ遷移"); state = BattleState.STATE_NOPLAYERS; } break; } /* * ゲームが稼働しているステート */ case BattleState.STATE_NOPLAYERS: case BattleState.STATE_PLAYERS_EXISTS: { // worldにいるユーザー = dummyの挙動を開始する。 world.UpdateWorld(gameFrame, StackPublish); UpdateXrossPeer(gameFrame); gameFrame++; break; } case BattleState.STATE_ENDING: { XrossPeer.TimeAssert(Develop.TIME_ASSERT, "とりあえずリセットをかける。クライアント側にはサーバリセット後の通信が届くので、そこから勝手に復帰させるといい感じになる。"); // 時間稼ぎとか。UniRxで10秒とかを計ると良いんだと思う。 STATE_ENDED state = BattleState.STATE_ENDED; break; } case BattleState.STATE_ENDED: { // do nothing yet. return(false); //SAYONARA!!! } default: { XrossPeer.Log("message received at missing state:" + state); break; } } /* * send stacked data to players. */ PublishStackedData(); return(true); }
public void Setup(Action <string, byte[]> Send) { XrossPeer.Log("server ready:" + serverContextId); XrossPeer.TimeAssert(Develop.TIME_ASSERT, "リセットを兼ねることはしない方が良いんだろうか。"); // 仮の、ゲームに参加するconnectionIdを保持しておくレイヤ reservationLayer = new ReservationLayer(Send); this.Send = Send; }
/* * enque data on receive. */ public void EnqueOnReceive(string connectionId, byte[] data) { XrossPeer.TimeAssert(Develop.TIME_ASSERT, "接続者が他人のplayerIdでデータを送ってきた場合、データを展開した瞬間にバレさせることができる。一度発見したら強制切断しよう。"); var playerId = PlayerIdFromConnectionId(connectionId); if (string.IsNullOrEmpty(playerId)) { XrossPeer.Log("不明なconnectionIdからのデータ:" + connectionId + " 内容は、:" + Encoding.UTF8.GetString(data)); return; } lock (gameDataQueue) gameDataQueue.Enqueue(new DataPack(playerId, data)); }
public ReservationLayer(Action <string, byte[]> publish) { XrossPeer.TimeAssert(Develop.TIME_ASSERT, "とりあえず通過できるtokenとして特定のplayerIdを直書きしてある。"); var reservedPlayerIds = new List <string> { "_empty_", }; /* * acceptable id is 100 ~ 199 */ for (var i = 100; i < 200; i++) { reservedPlayerIds.Add(i.ToString()); } reservationLayerId = Guid.NewGuid().ToString(); gameLayer = new GameContextLayer(reservedPlayerIds, publish); }
public void EnqueueOnDisconnect(string connectionId, string token, string reason) { XrossPeer.TimeAssert(Develop.TIME_ASSERT, "tokenそのまま使ってるんで、このままの構造だと、他人が偽って他プレイヤーの通信切断できちゃうな。プレイヤーしかしらないパラメータを使ってplayerIdを読みだす仕組みをつくらんとな。 具体的にはtokenが"); var playerId = token; var data = new Commands.OnDisconnected(playerId, reason).ToData(); XrossPeer.TimeAssert(Develop.TIME_ASSERT, "disconnect. とりあえずすべてのconnectionIdに対して、このreserveレイヤに登録があった、みたいなみなしをしてうけいれる。"); if (true) { // remove connectionId from reserved playerId. var succeeded = gameLayer.DiscardConnectionIdOfPlayerId(playerId); if (!succeeded) { XrossPeer.Log("playerId:" + playerId + " のconnectionの廃棄に失敗した。存在しないプレイヤーからの切断っぽい。"); } /* * すでに切断されているので、このプレイヤーへの通信はこの時点で不可能。 */ gameLayer.EnqueOnDisconnect(playerId, data); } }
/** * ServerContextの終了手続き */ public void Teardown() { XrossPeer.TimeAssert(Develop.TIME_ASSERT, "ContextのTeardown処理、なんか必要かな、、"); }