using Client; using SharedClientServer; using System; using System.Collections.Generic; using System.Diagnostics; using System.Net; using System.Net.Sockets; using System.Text; namespace Server.Models { class ServerCommunication : ObservableObject { private TcpListener listener; private List serverClients; public bool Started = false; public List lobbies; private Dictionary> serverClientsInlobbies; public Action newClientAction; /// /// use a padlock object to make sure the singleton is thread-safe /// private static readonly object padlock = new object(); private static ServerCommunication instance = null; public int port = 5555; private ServerCommunication() { listener = new TcpListener(IPAddress.Any, port); serverClients = new List(); lobbies = new List(); Lobby temp = new Lobby(1, 7, 8); lobbies.Add(temp); serverClientsInlobbies = new Dictionary>(); serverClientsInlobbies.Add(temp, new List()); } /// /// returns the singleton serverCommunication instance /// public static ServerCommunication INSTANCE { get { lock (padlock) { if (instance == null) { instance = new ServerCommunication(); } } return instance; } } /// /// start the server and start listening on port 5555 and begin acceptinc tcp clients /// public void Start() { listener.Start(); Debug.WriteLine($"================================================\nStarted Accepting clients at {DateTime.Now}\n================================================"); Started = true; // when we have accepted a tcp client, call the onclientconnected callback method listener.BeginAcceptTcpClient(new AsyncCallback(OnClientConnected), null); } /// /// callback method that gets called when a client is accepted /// /// the result of the asynchronous connect call private void OnClientConnected(IAsyncResult ar) { // stop the acceptation var tcpClient = listener.EndAcceptTcpClient(ar); Debug.WriteLine($"Got connection from {tcpClient.Client.RemoteEndPoint}"); newClientAction.Invoke(); // create a new serverclient object and add it to the list serverClients.Add(new ServerClient(tcpClient)); //start listening for new tcp clients listener.BeginAcceptTcpClient(new AsyncCallback(OnClientConnected), null); } /// /// send a message to all tcp clients in the list /// /// the message to send public void sendToAll(byte[] message) { foreach (ServerClient sc in serverClients) { sc.sendMessage(message); } } public void SendToAllExcept(string username, byte[] message) { foreach (ServerClient sc in serverClients) { if (sc.User.Username != username) sc.sendMessage(message); } } public void SendToLobby(Lobby lobby, byte[] message) { foreach (Lobby l in lobbies) { if (l == lobby) { foreach (ServerClient sc in serverClientsInlobbies[l]) { sc.sendMessage(message); } break; } } } public void AddToLobby(Lobby lobby, User user) { foreach (Lobby l in lobbies) { if (l == lobby) { bool succ; l.AddUser(user, out succ); Debug.WriteLine("[SERVERCOMM] added user to lobby, now contains " + l.PlayersIn); if (!succ) { // TODO send lobby full message } else { foreach(ServerClient sc in serverClients) { if (sc.User.Username == user.Username) { serverClientsInlobbies[l].Add(sc); break; } } } break; } } } public int HostForLobby(User user) { Lobby lobby = new Lobby( lobbies.Count + 1,0, 8); lobbies.Add(lobby); serverClientsInlobbies.Add(lobby, new List()); user.Host = true; AddToLobby(lobby, user); return lobby.ID; } public void JoinLobby(User user, int id) { foreach (Lobby l in lobbies) { if (l.ID == id) { AddToLobby(l, user); Debug.WriteLine($"{user.Username} joined lobby with id {id}"); break; } } } } }