/// <summary> /// wait for connection phase of this agent encounter the specified 'phase' /// </summary> /// <param name="ph"></param> public void WaitTill(ConnectionPhase ph) { while (Phase < ph) { Thread.Sleep(1); } }
// // Lifecycle // internal void OnConnecting(CancellationToken cancellationToken) { _phase = _hasConnected ? ConnectionPhase.Reconnecting : ConnectionPhase.Connecting; CancellationToken = cancellationToken; _cancellationTokenRegistration = cancellationToken.Register(OnCancelled); }
internal void OnConnecting(CancellationToken cancellationToken) { Phase = ConnectionPhase.Connecting; CancellationToken = cancellationToken; _cancellationTokenRegistration = cancellationToken.Register(OnCancelled); }
/// <summary> /// Set the phase of the internal connection state machine, optionally adding a delay. /// </summary> /// <param name="phase"></param> /// <param name="delay"></param> private void SetConnectionPhase(ConnectionPhase phase, float delay = 0.0f) { if (delay > 0.0f) { _nextConnectionStateTime = Time.unscaledTime + delay; } else { _nextConnectionStateTime = 0.0f; } _connectionPhase = phase; }
internal void OnConnected() { if (_hasConnected) { _phase = ConnectionPhase.Reconnected; } else { _phase = ConnectionPhase.Connected; _hasConnected = true; } }
/// <summary> /// Initializes a new instance of the <see cref="NetServerEventArgs"/> class. /// </summary> public NetServerEventArgs() { serverinstruction = ServerInstructionType.Unknown; ConnectPhase = ConnectionPhase.error; }
/// <summary> /// Game Server Status Event Arguments /// </summary> /// <param name="phase"> /// Server <see cref="ConnectionPhase"/> /// </param> /// <param name="Instruction"> /// Game <see cref="ServerInstructionType"/> to client /// </param> public NetServerEventArgs(ConnectionPhase phase, ServerInstructionType Instruction = ServerInstructionType.Unknown) { ConnectPhase = phase; serverinstruction = Instruction; }
/// <summary> /// Constructor /// </summary> /// <param name="clientdata"> /// Optional Message /// </param> /// <param name="phase"> /// Connection Phase /// </param> public NetClientEventArgs(ConnectionPhase phase, string clientdata = null) { ConnectPhase = phase; message = clientdata; }
/// <summary> /// watch dog has the highest authority in agent, it performs some light weight operations, such as update 'TCounters' /// </summary> private void __threadWatchdog(ThreadControl control) { logger.Debug($"{nameof(__threadWatchdog)}() on duty."); var feedCycle = Math.Min(1000, this.timeout >> 1); // the cycle of dog feeding, unit: ms var feedTCounter = 0; var msg = new EMessage(0); var foodBag = new[] { DOG_FOOD_FLAG }; var threadInterval = 1; // watch dog scan cycle, ms while (!control.SafelyTerminating) { Thread.Sleep(threadInterval); // -1 denote that the dog is dead,only __threadListen can set it back to '0' to rebirth the dog if (watchDog == -1) { continue; // no more actions when dog has died } /******************* * update TCounters * *****************/ KeyValuePair <uint, TCounter>[] msgIdAndTCounterPairs; lock (dictMsgId2TC) msgIdAndTCounterPairs = dictMsgId2TC.ToArray(); foreach (var kv in msgIdAndTCounterPairs) { if (kv.Value.Decrease(threadInterval) || !this.IsConnected) // request timeout { kv.Value.CountDown = 0; // set countdown to 'timeout' RemoveWaitFlag(kv.Key); ThreadPool.QueueUserWorkItem(_processTimeoutMessage, kv.Value.RequestMsg); } } /************ * watch dog * **********/ if (IsConnected) { // check local dog watchDog += threadInterval; if (watchDog >= timeout) { watchDog = -1; // time out flag GetControl(ThreadType.Listen).SafeAbort(); OnConnectionTimeout(); logger.Error($"{this} connection timeout."); } // feed remote dog feedTCounter += threadInterval; if (feedTCounter >= feedCycle) { feedTCounter = 0; // reset try { SendBytes(foodBag, 0, foodBag.Length); } catch { // pass, ignore all errors } } } } control.SetAbortedFlags(); logger.Debug($"{nameof(__threadWatchdog)}() aborted."); this.Destroy(); this.Phase = ConnectionPhase.P0Start; }
internal void OnDisconnected() { Phase = ConnectionPhase.Disconnected; }
internal void OnDisconnecting() { Phase = ConnectionPhase.Disconnecting; UnregisterCancellationToken(); }
internal void OnConnected() { Phase = ConnectionPhase.Connected; }
internal void OnConnectFailed() { Phase = ConnectionPhase.Disconnected; CancellationToken = default(CancellationToken); }
// // Expectations // public void ExpectPhase(ConnectionPhase phase) { Expect(_phase).Is(phase, "Connection is in the wrong phase"); }
private static bool HandleSetup(Client client, ref ConnectionPhase phase, GameDataAction input, ref bool handled) { if (input.Data.ContainsKey("deck")) { handled = true; var deckData = input.Data["deck"].String(); var ids = deckData.Split(','); if (ids.Length == Deck.CardLimit) { client.Player.Deck = new Deck(); var usedIDs = new Dictionary<string, int>(); foreach (var id in ids) { int current; if (usedIDs.TryGetValue(id, out current)) { if (current < Deck.CardDuplicateLimit) { usedIDs[id] = current+1; } else { CloseConnection(client, ErrorCode.InvalidDeck, $"More than {Deck.CardDuplicateLimit} of card id '{id}' detected in deck."); } } else { usedIDs.Add(id, 1); } var card = Game.Cards[id].CreateInstance(); //Game.Board.Cards.Add(card.UID, card); client.Player.Deck.PushRandom(card); } client.Writer.SendAction(GameAction.Meta, new Dictionary<string, GameData> { { "deckvalid", 1 } }); client.Player.SetupComplete = true; if (Players.Count == PlayerAmount && Players.All(x => x.SetupComplete)) { Game.StartGame(Players); } } else { CloseConnection(client, ErrorCode.InvalidDeck, $"Invalid amount of cards, deck requires {Deck.CardLimit}. {ids.Length} cards were recieved."); } } return handled; }
void OnCancelled() { Phase = ConnectionPhase.Cancelled; UnregisterCancellationToken(); }
private static void HandleHandshake(Client client, ref ConnectionPhase phase, GameDataAction input, ref bool handled) { if (input.Data.ContainsKey("protocol")) { if (input.Data["protocol"] != GameActionWriter.PROTOCOL_VERSION.ToString()) { CloseConnection(client, ErrorCode.VersionMismatch, $"Server version: {GameActionWriter.PROTOCOL_VERSION} - Client Version: {input.Data["protocol"]}"); handled = true; } } if (input.Data.ContainsKey("name")) { client.Player.Name = input.Data["name"]; handled = true; phase = ConnectionPhase.Setup; client.Writer.SendAction(GameAction.Meta, new Dictionary<string, GameData> { {"phase", ConnectionPhase.Setup} }); } }
private async void GetData(Client c) { while (c.RawClient.Connected) { var line = await c.Reader.ReadLineAsync(); var input = new GameDataAction(line); AddLine(input); if (input.Action == GameAction.Ping) { if (input.Data["counter"].Int() == (++_pingCounter)) { AddLine("Ping Success."); } else { AddLine("WARNING: Ping Failure!!!!!!"); } } else if (input.Action == GameAction.Meta) { if (input.Data.ContainsKey("phase")) { Phase = input.Data["phase"]; switch (Phase) { case ConnectionPhase.Handshake: // This shouldn't occur, is the starting phase. break; case ConnectionPhase.Setup: OnSetupPhase(); break; case ConnectionPhase.Game: OnGamePhase(); break; default: throw new ArgumentOutOfRangeException(); } } } else if (input.Action == GameAction.GameStart) { PlayerID = input.Data["number"]; Players = input.Data["players"]; } else if (input.Action == GameAction.DrawCard) { if (input.Data["player"] == PlayerID) { string cardID = input.Data["card"]; var card = Game.Cards[cardID].CreateInstance(); AddCard($"{cardID}\n{card.Cost}\n{card.Type}"); } } } lbRecieved.Items.Add("Disconnected."); }