public void UnregisterConnection(ILowProtocol client) { lock (m_protocolToClientId) { lock (m_incomingMessages) { if (m_protocolToClientId.ContainsKey(client)) { Guid guid = m_protocolToClientId[client]; m_clientIdToProtocol.Remove(guid); m_protocolToClientId.Remove(client); if (guid != Guid.Empty) { OnUnregisterClientSafe(client, guid); } Log.Info("Unregister Connection for client " + guid); client.Message -= OnIncomingMessage; client.Request -= OnIncomingRequest; } } } }
protected void Return(ILowProtocol sender, LowRequestArgs request, Error error, params RemoteArg[] args) { RemoteResult remoteResult = new RemoteResult(error, args); byte[] result = m_serializer.Serialize(remoteResult); EnqueueResponse(sender, request.Id, result); }
protected override void OnRegisterClientSafe(ILowProtocol protocol, Guid clientId) { base.OnRegisterClientSafe(protocol, clientId); //Sync method call no fail m_gameServer.RegisterClient(clientId, error => { }); }
public void Connect() { if (m_protocol == null) { m_settings = Dependencies.Settings; m_wasConnected = false; m_protocol = new LowProtocol <Socket>(ServerUrl, Time.realtimeSinceStartup); m_protocol.Enabled += OnEnabled; m_protocol.Disabled += OnDisabled; m_protocol.SocketError += OnSocketError; m_protocol.Message += OnMessage; } m_wasConnected = IsConnected; IsConnectionStateChanging = true; if (ConnectionStateChanging != null) { ConnectionStateChanging(new Error(StatusCode.OK)); } m_protocol.Enable(); }
private void OnEnabled(ILowProtocol sender) { m_protocol.Enabled -= OnEnabled; m_call(); m_call = null; }
protected override void UnregisterConnection(ILowProtocol protocol) { lock (m_containers) { MatchServerContainer container; if (m_containers.TryGetValue(m_roomId, out container)) { container.UnregisterConnection(protocol); } } }
protected virtual void OnDisabled(ILowProtocol sender) { IsConnectionStateChanging = false; if (ConnectionStateChanged != null) { ConnectionStateChanged(new Error(StatusCode.OK), new ValueChangedArgs <bool>(m_wasConnected, false)); } m_wasConnected = false; }
private void EnqueueSend(ILowProtocol sender, byte[] data) { QueuedMessage message = new QueuedMessage(sender, data); if (m_outgoingMessages.Count == 0) { Monitor.PulseAll(m_outgoingMessages); } m_outgoingMessagesFrequency.Increment(); m_outgoingMessages.Enqueue(message); }
private void Dispose() { if (m_protocol != null) { m_protocol.Dispose(); m_protocol.Enabled -= OnEnabled; m_protocol.Disabled -= OnDisabled; m_protocol.SocketError -= OnSocketError; m_protocol.Message -= OnMessage; m_protocol = null; } }
private void OnIncomingMessage(ILowProtocol sender, byte[] data) { lock (m_incomingMessages) { if (m_incomingMessages.Count == 0) { Monitor.PulseAll(m_incomingMessages); } m_incomingMessagesFrequency.Increment(); m_incomingMessages.Enqueue(new QueuedMessage(sender, data)); } }
private void OnIncomingRequest(ILowProtocol sender, LowRequestArgs args) { lock (m_incomingMessages) { if (m_incomingMessages.Count == 0) { Monitor.PulseAll(m_incomingMessages); } m_incomingMessagesFrequency.Increment(); m_incomingMessages.Enqueue(new QueuedMessage(sender, args)); } }
protected override void OnUnregisterClientSafe(ILowProtocol protocol, Guid clientId) { base.OnUnregisterClientSafe(protocol, clientId); //Sync method call no fail m_gameServer.UnregisterClient(clientId, error => { if (m_gameServer.HasError(error)) { Log.Error("Failed to Unregister Client: " + error.ToString()); } }); }
public void RegisterConnection(ILowProtocol client) { lock (m_protocolToClientId) { lock (m_incomingMessages) { Log.Info("Register Connection"); m_protocolToClientId.Add(client, Guid.Empty); client.Message += OnIncomingMessage; client.Request += OnIncomingRequest; } } }
protected void BroadcastAll(byte[] data) { lock (m_protocolToClientId) { lock (m_outgoingMessages) { foreach (KeyValuePair <Guid, ILowProtocol> kvp in m_clientIdToProtocol) { ILowProtocol protocol = kvp.Value; EnqueueSend(protocol, data); } } } }
protected virtual void OnEnabled(ILowProtocol sender) { RegisterClient(m_settings.ClientId, error => { IsConnectionStateChanging = false; if (ConnectionStateChanged != null) { ConnectionStateChanged(error, new ValueChangedArgs <bool>(m_wasConnected, true)); } m_wasConnected = true; }); }
protected override void OnUnregisterClientSafe(ILowProtocol protocol, Guid clientId) { base.OnUnregisterClientSafe(protocol, clientId); if (m_matchServer != null) { m_matchServer.UnregisterClient(clientId, error => { if (m_matchServer.HasError(error)) { Log.Error("m_matchServer.UnregisterClient. This method should never fail but it does.. " + error.ToString()); } ; }); } }
protected virtual void OnSocketError(ILowProtocol sender, SocketErrorArgs args) { IsConnectionStateChanging = false; Dispose(); if (ConnectionStateChanged != null) { ConnectionStateChanged(new Error(StatusCode.ConnectionError) { Message = args.Message }, new ValueChangedArgs <bool>(m_wasConnected, false)); } m_wasConnected = false; }
protected void EnqueueResponse(ILowProtocol sender, int requestId, byte[] data) { QueuedMessage message = new QueuedMessage(sender, new LowRequestArgs(requestId, data)); lock (m_outgoingMessages) { if (m_outgoingMessages.Count == 0) { Monitor.PulseAll(m_outgoingMessages); } m_outgoingMessagesFrequency.Increment(); m_outgoingMessages.Enqueue(message); } }
private void OnDisabled(ILowProtocol sender) { m_protocol.Enabled -= OnEnabled; m_protocol.SocketError -= OnError; m_protocol.Disabled -= OnDisabled; m_protocol.Dispose(); if (m_response != null) { m_response(null); } m_protocol = null; m_call = null; m_response = null; }
protected void RegisterClient(ILowProtocol protocol, Guid clientId) { lock (m_protocolToClientId) { lock (m_incomingMessages) { if (m_protocolToClientId.ContainsKey(protocol)) { Log.Info("Register Client " + clientId); m_protocolToClientId[protocol] = clientId; m_clientIdToProtocol.Add(clientId, protocol); OnRegisterClientSafe(protocol, clientId); } } } }
public void IsAlive(ServerEventHandler callback) { if (m_protocol != null) { throw new InvalidOperationException(); } LowProtocol <ClientSocket> protocol = new LowProtocol <ClientSocket>(m_url, m_time.Time); m_protocol = protocol; m_protocol.Enabled += OnEnabled; m_protocol.SocketError += OnError; m_protocol.Disabled += OnDisabled; m_response = externalError => { callback(externalError); }; m_call = () => { RemoteCall rpc = new RemoteCall(RemoteCall.Proc.IsAliveCheck, ServerContainer.ServerIdentity); Call(rpc, (error, remoteResult) => { m_response = externalError => { if (externalError != null) { callback(externalError); } else { callback(error); } }; m_protocol.Disable(); }); }; m_protocol.Enable(); }
private void OnError(ILowProtocol sender, SocketErrorArgs args) { m_protocol.Enabled -= OnEnabled; m_protocol.SocketError -= OnError; m_protocol.Disabled -= OnDisabled; m_protocol.Dispose(); if (m_response != null) { m_response(new Error(StatusCode.ConnectionError) { Message = args.Message }); } m_protocol = null; m_call = null; m_response = null; }
protected void BroadcastAllExcept(Guid except, byte[] data) { lock (m_protocolToClientId) { lock (m_outgoingMessages) { foreach (KeyValuePair <Guid, ILowProtocol> kvp in m_clientIdToProtocol) { if (kvp.Key == except) { continue; } ILowProtocol protocol = kvp.Value; EnqueueSend(protocol, data); } } } }
public void CreateMatch(Guid creatorClientId, Room room, Guid[] clientIds, Player[] players, ReplayData replay, ServerEventHandler callback) { if (m_protocol != null) { throw new InvalidOperationException(); } LowProtocol <ClientSocket> protocol = new LowProtocol <ClientSocket>(m_url + "create", m_time.Time); m_protocol = protocol; m_protocol.Enabled += OnEnabled; m_protocol.SocketError += OnError; m_protocol.Disabled += OnDisabled; m_response = externalError => { callback(externalError); }; m_call = () => { RemoteCall rpc = new RemoteCall(RemoteCall.Proc.CreateMatch, ServerContainer.ServerIdentity, RemoteArg.Create(creatorClientId), RemoteArg.Create(room), RemoteArg.Create(clientIds), RemoteArg.Create(players), RemoteArg.Create(replay)); Call(rpc, (error, remoteResult) => { m_response = externalError => { if (externalError != null) { callback(externalError); } else { callback(error); } }; m_protocol.Disable(); }); }; m_protocol.Enable(); }
protected override void UnregisterConnection(ILowProtocol socket) { GameServerContainer.Instance.UnregisterConnection(socket); }
protected override void OnMessage(ILowProtocol sender, byte[] message) { }
protected virtual void OnMessage(ILowProtocol sender, byte[] args) { RemoteEvent evt = m_serializer.Deserialize <RemoteEvent>(args); OnRemoteEvent(evt); }
protected override void OnRequest(ILowProtocol sender, LowRequestArgs request) { RemoteCall rpc; try { rpc = m_serializer.Deserialize <RemoteCall>(request.Data); } catch (Exception e) { Log.Error("Invalid RemoteCall format ", e); #warning This code is not tested sender.Disable(); throw; } switch (rpc.Procedure) { case RemoteCall.Proc.RegisterClient: { RegisterClient(sender, rpc.ClientId); Return(sender, request, new Error(StatusCode.OK)); } break; case RemoteCall.Proc.CreateMatch: { if (rpc.ClientId != ServerIdentity) { Return(sender, request, new Error(StatusCode.NotAuthorized)); } else { Guid creatorClientId = rpc.Get <Guid>(0); Room room = rpc.Get <Room>(1); Guid[] clientIds = rpc.Get <Guid[]>(2); Player[] players = rpc.Get <Player[]>(3); ReplayData replay = rpc.Get <ReplayData>(4); if (m_matchServer == null) { MatchServerImpl matchServer = new MatchServerImpl(this, m_path, creatorClientId, room, clientIds, players, replay); m_matchServer = matchServer; m_matchServer.Tick += OnTick; m_matchServer.ReadyToPlayAll += OnReadyToPlayAll; m_matchServer.Paused += OnPaused; m_matchServer.Ping += OnPing; m_matchServer.ChatMessage += OnChatMessage; } Return(sender, request, new Error(StatusCode.OK)); } } break; case RemoteCall.Proc.GetState: { m_matchServer.GetState(rpc.ClientId, (error, arg, arg2, arg3, arg4, arg5, arg6, arg7, arg8) => { Room room = arg7; if (room.Mode == GameMode.Replay) { Return(sender, request, error, RemoteArg.Create(arg), RemoteArg.Create(new Guid[0]), RemoteArg.Create(arg3), RemoteArg.Create(arg4), RemoteArg.Create(arg5), RemoteArg.Create(arg6), RemoteArg.Create(arg7), RemoteArg.Create(arg8)); } else { Dictionary <Guid, Dictionary <Guid, Player> > clientIdToPlayers = arg2; Dictionary <Guid, Player> players; if (!clientIdToPlayers.TryGetValue(rpc.ClientId, out players)) { Return(sender, request, new Error(StatusCode.NotFound)); } else { Return(sender, request, error, RemoteArg.Create(arg), RemoteArg.Create(players.Keys.ToArray()), RemoteArg.Create(arg3), RemoteArg.Create(arg4), RemoteArg.Create(arg5), RemoteArg.Create(arg6), RemoteArg.Create(arg7), RemoteArg.Create(arg8)); } } }); } break; case RemoteCall.Proc.GetReplay: m_matchServer.GetReplay(rpc.ClientId, (error, replayData, room) => { Return(sender, request, error, RemoteArg.Create(replayData), RemoteArg.Create(room)); }); break; case RemoteCall.Proc.DownloadMapData: m_matchServer.DownloadMapData(rpc.ClientId, (Error error, byte[] data) => { Return(sender, request, error, RemoteArg.Create(data)); }); break; case RemoteCall.Proc.ReadyToPlay: m_matchServer.ReadyToPlay(rpc.ClientId, error => { Return(sender, request, error); }); break; case RemoteCall.Proc.Submit: m_matchServer.Submit(rpc.ClientId, rpc.Get <int>(0), rpc.Get <Cmd>(1), (error, returnedCommand) => { Return(sender, request, error, RemoteArg.Create(returnedCommand)); }); break; case RemoteCall.Proc.SubmitResponse: m_matchServer.SubmitResponse(rpc.ClientId, rpc.Get <ClientRequest>(0), (error, response) => { Return(sender, request, error, RemoteArg.Create(response)); }); break; case RemoteCall.Proc.Pong: m_matchServer.Pong(rpc.ClientId, error => { Return(sender, request, error); }); break; case RemoteCall.Proc.Pause: m_matchServer.Pause(rpc.ClientId, rpc.Get <bool>(0), error => { Return(sender, request, error); }); break; case RemoteCall.Proc.IsAliveCheck: Return(sender, request, new Error(StatusCode.OK)); break; case RemoteCall.Proc.SendChatMessage: m_matchServer.SendMessage(rpc.ClientId, rpc.Get <ChatMessage>(0), (error, messageId) => { Return(sender, request, error, RemoteArg.Create(messageId)); }); break; } }
protected override void OnRequest(ILowProtocol sender, LowRequestArgs request) { RemoteCall rpc; try { rpc = m_serializer.Deserialize <RemoteCall>(request.Data); } catch (Exception e) { Log.Error("Invalid RemoteCall format ", e); //#warning Should force disconnect client #warning This code is not tested sender.Disable(); throw; } switch (rpc.Procedure) { case RemoteCall.Proc.RegisterClient: { RegisterClient(sender, rpc.ClientId); Return(sender, request, new Error(StatusCode.OK)); } break; case RemoteCall.Proc.GetPlayers: m_gameServer.GetPlayers(rpc.ClientId, (error, players) => { Return(sender, request, error, RemoteArg.Create(players)); }); break; case RemoteCall.Proc.GetPlayersByRoomId: m_gameServer.GetPlayers(rpc.ClientId, rpc.Get <Guid>(0), (error, players) => { Return(sender, request, error, RemoteArg.Create(players)); }); break; case RemoteCall.Proc.GetPlayer: m_gameServer.GetPlayer(rpc.ClientId, rpc.Get <Guid>(0), (error, players) => { Return(sender, request, error, RemoteArg.Create(players)); }); break; case RemoteCall.Proc.Login: m_gameServer.Login(rpc.Get <string>(0), rpc.Get <string>(1), rpc.ClientId, (error, playerId, pwdHash) => { Return(sender, request, error, RemoteArg.Create(playerId), RemoteArg.Create(pwdHash)); }); break; case RemoteCall.Proc.LoginHash: m_gameServer.Login(rpc.Get <string>(0), rpc.Get <byte[]>(1), rpc.ClientId, (error, playerId) => { Return(sender, request, error, RemoteArg.Create(playerId)); }); break; case RemoteCall.Proc.SignUp: m_gameServer.SignUp(rpc.Get <string>(0), rpc.Get <string>(1), rpc.ClientId, (error, playerId, pwdHash) => { Return(sender, request, error, RemoteArg.Create(playerId), RemoteArg.Create(pwdHash)); }); break; case RemoteCall.Proc.Logoff: m_gameServer.Logoff(rpc.ClientId, rpc.Get <Guid>(0), (error, guid) => { Return(sender, request, error, RemoteArg.Create(guid)); }); break; case RemoteCall.Proc.LogoffMultiple: m_gameServer.Logoff(rpc.ClientId, rpc.Get <Guid[]>(0), (error, guids) => { Return(sender, request, error, RemoteArg.Create(guids)); }); break; case RemoteCall.Proc.JoinRoom: m_gameServer.JoinRoom(rpc.ClientId, rpc.Get <Guid>(0), (error, room) => { //Boradcast to room players Return(sender, request, error, RemoteArg.Create(room)); }); break; case RemoteCall.Proc.LeaveRoom: m_gameServer.LeaveRoom(rpc.ClientId, (error) => { //Brodcast to room players Return(sender, request, error); }); break; case RemoteCall.Proc.GetRooms: m_gameServer.GetRooms(rpc.ClientId, rpc.Get <int>(0), rpc.Get <int>(1), (error, rooms) => { Return(sender, request, error, RemoteArg.Create(rooms)); }); break; case RemoteCall.Proc.GetRoom: m_gameServer.GetRoom(rpc.ClientId, (error, room) => { Return(sender, request, error, RemoteArg.Create(room)); }); break; case RemoteCall.Proc.GetRoomById: m_gameServer.GetRoom(rpc.ClientId, rpc.Get <Guid>(0), (error, room) => { Return(sender, request, error, RemoteArg.Create(room)); }); break; case RemoteCall.Proc.CreateRoom: m_gameServer.CreateRoom(rpc.ClientId, rpc.Get <Guid>(0), rpc.Get <GameMode>(1), (error, room) => { //Do not broadcast //client will get rooms list using polling each 10 seconds //or using refres button Return(sender, request, error, RemoteArg.Create(room)); }); break; case RemoteCall.Proc.DestroyRoom: m_gameServer.DestroyRoom(rpc.ClientId, rpc.Get <Guid>(0), (error, guid) => { Return(sender, request, error, RemoteArg.Create(guid)); }); break; case RemoteCall.Proc.CreateBot: m_gameServer.CreateBot(rpc.ClientId, rpc.Get <string>(0), rpc.Get <BotType>(1), (error, playerId, room) => { Return(sender, request, error, RemoteArg.Create(playerId), RemoteArg.Create(room)); }); break; case RemoteCall.Proc.CreateBots: m_gameServer.CreateBots(rpc.ClientId, rpc.Get <string[]>(0), rpc.Get <int[]>(1).ToEnum <BotType>(), (error, playerIds, room) => { Return(sender, request, error, RemoteArg.Create(playerIds), RemoteArg.Create(room)); }); break; case RemoteCall.Proc.DestroyBot: m_gameServer.DestroyBot(rpc.ClientId, rpc.Get <Guid>(0), (error, playerId, room) => { Return(sender, request, error, RemoteArg.Create(playerId), RemoteArg.Create(room)); }); break; case RemoteCall.Proc.UploadMapData: m_gameServer.UploadMap(rpc.ClientId, rpc.Get <MapInfo>(0), rpc.Get <byte[]>(1), (error) => { Return(sender, request, error); }); break; case RemoteCall.Proc.GetMaps: m_gameServer.GetMaps(rpc.ClientId, (Error error, ByteArray[] mapsInfo) => { Return(sender, request, error, RemoteArg.Create(mapsInfo)); }); break; case RemoteCall.Proc.DownloadMapData: m_gameServer.DownloadMapData(rpc.ClientId, rpc.Get <Guid>(0), (Error error, byte[] mapData) => { Return(sender, request, error, RemoteArg.Create(mapData)); }); break; case RemoteCall.Proc.GetReplays: m_gameServer.GetReplays(rpc.ClientId, (Error error, ByteArray[] replaysInfo) => { Return(sender, request, error, RemoteArg.Create(replaysInfo)); }); break; case RemoteCall.Proc.SetReplay: m_gameServer.SetReplay(rpc.ClientId, rpc.Get <Guid>(0), (error) => { Return(sender, request, error); }); break; case RemoteCall.Proc.SaveReplay: m_gameServer.SaveReplay(rpc.ClientId, rpc.Get <string>(0), (error) => { Return(sender, request, error); }); break; case RemoteCall.Proc.GetStats: m_gameServer.GetStats(rpc.ClientId, (error, serverStats) => { Return(sender, request, error, RemoteArg.Create(serverStats)); }); break; case RemoteCall.Proc.SetReadyToLaunch: m_gameServer.SetReadyToLaunch(rpc.ClientId, rpc.Get <bool>(0), (error, room) => { Return(sender, request, error, RemoteArg.Create(room)); }); break; case RemoteCall.Proc.Launch: m_gameServer.Launch(rpc.ClientId, (error, serverUrl) => { Return(sender, request, error, RemoteArg.Create(serverUrl)); }); break; case RemoteCall.Proc.SendChatMessage: m_gameServer.SendMessage(rpc.ClientId, rpc.Get <ChatMessage>(0), (error, messageId) => { Return(sender, request, error, RemoteArg.Create(messageId)); }); break; } }
protected override void OnMessage(ILowProtocol sender, byte[] message) { Log.Error("Unknow message"); }