public Guid RegisterOperationHandler <T>(Action <T> handler, bool callOnce = false) where T : MessageBase, new() { var id = Guid.NewGuid(); var operationCode = GetOperationCode <T>(); _logger.Debug( $"Registering OperationHandler {handler.Method} for operation {operationCode} (callOnce = {callOnce})"); if (!_handlers.TryGetValue(operationCode, out var eventHandlers)) { eventHandlers = new ConcurrentDictionary <Guid, EventHandler>(); _handlers.TryAdd(operationCode, eventHandlers); } if (!_parsers.ContainsKey(operationCode)) { _parsers.TryAdd(operationCode, (data, offset, length) => _serializer.DeserializeAs <T>(data, offset, length)); } eventHandlers.TryAdd(id, new EventHandler(msgBase => handler((T)msgBase), callOnce)); _handlerIdToOperationCodes[id] = operationCode; return(id); }
public virtual void Start() { Logger.Info($"Starting"); //initialize peer collection PeerCollection = new PeerCollection <TP>(Logger, Serializer, Config); Logger.Debug($"Peer collection initialized as {PeerCollection.GetType()}"); //initialize packers // Serializer.InitializeDefaultSerializers(8, $"Simple{this.GetType()}Buffer"); Logger.Debug($"Serializer factory initialized as {Serializer.GetType()}"); //initialize listener foreach (var port in Config.ListenPorts) { var peerListener = new TL(); peerListener.Initialize(Logger, PeerCollection, Serializer, Config, TaskSchedulerFactory, port, SocketFactory, RequestSender, _protectionManager); PeerListeners.Add(peerListener); Logger.Info($"PeerListener initialized as {peerListener.GetType()} on port {port}"); } //call child sub logic OnStart(); //start listening and processing messages Listen(); // checking GC influence TaskScheduler.ScheduleOnInterval(TrackMetrics, 1000, 1000); }
private void SendJoinInfoToCurrentMatchmakingGroup() { lock (_queueSync) { foreach (var player in _matchmakingPlayers) { _logger.Debug($"Sending prejoin info to {player.Id}"); var joinInfo = new JoinInfo("", 0, Guid.Empty, JoinStatus.OnMatchmaking, GetCurrentPlayersWeight(), _totalPlayersNeeded); _messageSender.Send(new JoinInfoEvent(joinInfo), player.Peer); } } }
public async Task UpdateRoomState(Guid roomId, int roomPlayersCount, RoomState roomState, string matchMakerUrl, int maxMatchMakingWeight) { try { if (string.IsNullOrWhiteSpace(matchMakerUrl)) { _logger.Error($"SendRoomStateUpdate error: matchmaker URL is empty in properties container"); return; } await _requestSender.SendRequest <UpdateRoomStateResponse>(matchMakerUrl, new UpdateRoomStateRequest(roomId, roomPlayersCount, roomState, maxMatchMakingWeight), (r) => { if (!r.Success) { _logger.Error($"Room update error: {r.Message}"); } else { _logger.Debug($"Room update to {matchMakerUrl} with players count {roomPlayersCount}, state {roomState} successful"); } }); } catch (Exception e) { _logger.Error($"Update room state error: {e}"); } }
public void Connect(string address, int port) { //switch Sockets implementation.BEGIN //_socket = new HazelSock(_logger); _socket = new LiteNetSock(_logger); //switch sockets implementation.END _socket.OnPacketReceived += (endPoint, dataPacket, release) => { _onPackageReceived(dataPacket, release); //todo if using hazel then this part should be considered in releaseAction param // _socket.ReturnBufferToPool(dataPacket.Buffer); }; _socket.OnDisconnected += OnDisconnected; _socket.OnConnected += ep => { OnConnectedToServer?.Invoke(); }; _ep = GetIPEndPointFromHostName(address, port, false); // new IPEndPoint(IPAddress.Parse(address), port); _socket.Connect(_ep); _connected = true; _isTicking = false; //Send(new ConnectedEvent()); _socketTickTask = _taskScheduler.ScheduleOnInterval(() => { lock (_stateSync) { if (!_connected) { return; } lock (_isTickingMutex) { if (_isTicking) { return; } _isTicking = true; } try { _socket.Tick(); } catch (Exception ex) { _logger.Error($"Socket tick error: {ex}"); } finally { lock (_isTickingMutex) _isTicking = false; } } }, 0, 10); _logger?.Debug($"Receive loop started"); }
public void UpdateRoomState(Guid roomId, int currentPlayers, RoomState roomState, int currentMaxWeight) { var room = GetRoom(roomId); if (room == null) { _logger.Error($"UpdateRoomState error: no room with id {roomId}"); return; } room.MaxWeightToJoin = currentMaxWeight; room.CurrentWeight = currentPlayers; room.UpdateState(roomState); _logger.Debug($"Update received: {roomId} State {roomState}"); }
public void Remove(IPendingTask task) { var pt = task as PendingTask; if (pt == null) { return; } lock (_listLock) { var pendingTask = _tasks.FirstOrDefault(t => t == pt); if (pendingTask == null) { return; } _logger?.Debug($"Removing {pendingTask.GetActionName()}"); pendingTask.Dispose(); _tasks.Remove(pt); } }
private void ProcessMessage(byte[] buffer, int offset, int length) { MessageBase deserialized = null; ushort operationCode = 0; try { //probably bad kind of using var message = new ArraySegment <byte>(buffer, offset, length).ToArray(); operationCode = MessageBase.GetOperationCode(message); _logger.Debug($"Message received. Operation code: {operationCode}"); deserialized = _messageDeserializer.DeserializeMessage(operationCode, _serializer, message); } catch (Exception ex) { _logger.Error($"ClientOnPackageReceived error: {ex}"); } //calling registered handlers lock (_syncCollections) { if (deserialized != null && operationCode != 0 && _handlers.ContainsKey(operationCode)) { var callbacksToUnregister = new List <Guid>(); foreach (var item in _handlers[operationCode]) { try { item.Value.Handler.Invoke(deserialized); if (item.Value.CallOnce) { callbacksToUnregister.Add(item.Key); } } catch (Exception ex) { string targetName = item.Value == null ? "" : item.Value.Handler.Method.ToString(); _logger.Error($"ClientOnPackageReceived error: processing message {deserialized.OperationCode} in handler {targetName} {ex}"); } } //unregister foreach (var item in callbacksToUnregister) { UnregisterOperationHandler(item); } } else { _logger.Debug($"No handler for message {operationCode}"); } } }
private void OmMmAuthorizationResponse(AuthorizationResponse response) { _logger.Debug($"JoinGame: AuthorizationRequest callback fired"); if (response.ResultCode != ResultCode.OK) { _logger.Debug($"JoinGame: AuthorizationResponse error: {response.ResultCode}"); SetAndReportStatus(ShamanClientStatus.AuthorizingMatchMaking, _statusCallback, false, $"AuthorizationResponse error: {response.ResultCode}"); return; } _logger.Debug($"JoinGame: Entering matchmaking"); //calling next stage switch (_joinType) { case JoinType.RandomJoin: _taskScheduler.ScheduleOnceOnNow(EnterMatchMaking); break; // case JoinType.DirectJoin: // _taskScheduler.ScheduleOnceOnNow(GetRooms); // break; // case JoinType.CreateGame: // _taskScheduler.ScheduleOnceOnNow(CreateGame); // break; default: throw new ArgumentOutOfRangeException(); } }