예제 #1
0
        private void SendAliveNextPeer()
        {
            try
            {
                while (true)
                {
                    Logger.WriteLine("SendAliveNextPeer");
                    byte[] buffer = new byte[1024];

                    lock (nextPeerPaddle)
                    {
                        if (nextPeerSocket == null)
                        {
                            Thread.Sleep(Configuration.MaxTimeout / 2);
                            continue;
                        }

                        Message mes = Message.CreateMessageKeepAlive(PeerId);
                        nextPeerSocket.Send(mes.data, 0, mes.data.Length, SocketFlags.None);
                        nextPeerSocket.Receive(buffer, 0, buffer.Length, SocketFlags.None);
                    }

                    Message response = new Message(buffer);
                    if (response.GetMessageType() == Message.MessageType.KeepAlive)
                    {
                        Logger.WriteLine("KeepAlive to next peer success.");
                        Thread.Sleep(Configuration.MaxTimeout / 2);
                    }
                    else
                    {
                        Logger.WriteLine("Message KeepAlive reply from next peer has not been received.");
                        lock (nextPeerPaddle)
                        {
                            Logger.WriteLine("Closing connection " + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Address + ":" + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Port);
                            nextPeerSocket.Close();
                        }
                        break;
                    }
                    Logger.WriteLine();
                }
            }
            catch (Exception e)
            {
                Logger.WriteLine(e.Message);
            }
        }
예제 #2
0
        public void Quit()
        {
            try
            {
                if ((IsConnected) && (IsInRoom))
                {
                    Logger.WriteLine("Requesting to quit room");

                    Message request = Message.CreateMessageQuit(PeerId);
                    byte[] buffer = new byte[1024];

                    lock (nextPeerPaddle)
                    {
                        nextPeerSocket.Send(request.data, 0, request.data.Length, SocketFlags.None);
                        nextPeerSocket.Receive(buffer, buffer.Length, SocketFlags.None);
                    }

                    Message response = new Message(buffer);
                    Message.MessageType responseType = response.GetMessageType();
                    if (responseType == Message.MessageType.Success)
                    {
                        nextPeerSocket.Close();
                        nextPeerSocket = null;
                        listenerSocket.Disconnect(true);
                    }
                    else
                    {
                        Logger.WriteLine("Quit is prohibited");
                    }
                }
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.ToString());
            }
        }
예제 #3
0
        private void ReceiveCallback(IAsyncResult target)
        {
            Logger.WriteLine("--- ReceiveCallback");
            Message.MessageType requestType = Message.MessageType.Unknown;
            Socket handler = null;
            try
            {
                object[] obj = new object[2];
                obj = (object[])target.AsyncState;

                byte[] buffer = (byte[]) obj[0];
                handler = (Socket) obj[1];

                Logger.WriteLine("ReceiveCallback from " + (handler.RemoteEndPoint as IPEndPoint).Address + ":" + (handler.RemoteEndPoint as IPEndPoint).Port);

                bool quit = false;

                int bytesRead = handler.EndReceive(target);
                if (bytesRead > 0)
                {
                    Message request = new Message(buffer);
                    Message response;

                    requestType = request.GetMessageType();
                    if (requestType == Message.MessageType.HandshakePeerCreator) // Peer client mau join ke room ini
                    {
                        #region Handshake
                        Logger.WriteLine("HandshakePeerCreator");
                        if (Room.Members.Count < Room.MaxPlayer)
                        {
                            int newPeerId, newPeerListenPort;
                            IPAddress newPeerIp = (handler.RemoteEndPoint as IPEndPoint).Address;
                            request.GetHandshakePeerCreator(out newPeerId, out newPeerListenPort);
                            Room.Members.Add(new Peer(newPeerId, newPeerIp, newPeerListenPort));

                            Logger.WriteLine("Peer ID : " + newPeerId);
                            Logger.WriteLine("Peer IP : " + newPeerIp + ":" + newPeerListenPort);

                            // Send SUCCESS message
                            response = Message.CreateMessageSuccess();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);

                            if (nextPeerSocket != null)
                            {
                                Logger.WriteLine("Sending NEW MEMBER to nextPeerSocket: " + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Address + ":" + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Port);
                                // Send NewMember message to next peer
                                response = Message.CreateMessageNewMember(newPeerId, (handler.RemoteEndPoint as IPEndPoint).Address, newPeerListenPort);
                                nextPeerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);
                            }
                            else
                            {
                                IPEndPoint ipEndPoint = new IPEndPoint(newPeerIp, newPeerListenPort);
                                nextPeerSocket = new Socket(
                                    newPeerIp.AddressFamily,
                                    SocketType.Stream,
                                    ProtocolType.Tcp
                                   );
                                nextPeerSocket.NoDelay = false;
                                nextPeerSocket.Connect(ipEndPoint);

                                Logger.WriteLine("Setting up nextPeerSocket to " + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Address + ":" + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Port);

                                response = Message.CreateMessageRoomModel(Room);
                                nextPeerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);
                                Logger.WriteLine("Send room info");

                                keepAliveRoom = new Thread(new ThreadStart(SendAliveNextPeer));
                                keepAliveRoom.Start();
                            }

                            response = Message.CreateMessageAdd(newPeerId, Room.RoomId);
                            lock (trackerPaddle)
                            {
                                trackerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);
                                byte[] bufferRecv = new byte[1024];
                                trackerSocket.Receive(bufferRecv, 0, bufferRecv.Length, SocketFlags.None);
                            }
                        }
                        else
                        {
                            Logger.WriteLine("Send FAILED: Room penuh");
                            // Send FAILED message akibat ruang penuh
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                            handler.Close();
                            quit = true;
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.KeepAlive)
                    {
                        #region Keep Alive
                        int peerId;
                        request.GetKeepAlive(out peerId);
                        Peer peer = Room.Members.Find(fpeer => fpeer.PeerId == peerId);
                        if (peer != null)
                        {
                            //Send KeepAlive Message back
                            response = request;
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        else
                        {
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.NewMember)
                    {
                        #region NewMember
                        Logger.WriteLine("NewMember");
                        if (IsCreator)
                        {
                            Logger.WriteLine("NewMember has been received by peer creator");
                            Logger.WriteLine("Closing connection from " + (handler.RemoteEndPoint as IPEndPoint).Address + ":" + (handler.RemoteEndPoint as IPEndPoint).Port);
                            handler.Close();
                            quit = true;
                        }
                        else
                        {
                            bool isLast = Room.Members.Last().PeerId == PeerId;

                            int newPeerId, newPeerListenPort;
                            IPAddress newPeerIp;
                            request.GetNewMember(out newPeerId, out newPeerIp, out newPeerListenPort);
                            Room.Members.Add(new Peer(newPeerId, newPeerIp, newPeerListenPort));

                            Logger.WriteLine("Sending NEW MEMBER to nextPeerSocket: " + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Address + ":" + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Port);
                            response = request;
                            nextPeerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);

                            if (isLast)
                            {
                                Logger.WriteLine("Closing connection " + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Address + ":" + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Port);
                                nextPeerSocket.Close();

                                IPEndPoint ipEndPoint = new IPEndPoint(newPeerIp, newPeerListenPort);
                                nextPeerSocket = new Socket(
                                    newPeerIp.AddressFamily,
                                    SocketType.Stream,
                                    ProtocolType.Tcp
                                   );

                                nextPeerSocket.NoDelay = false;
                                nextPeerSocket.Connect(ipEndPoint);

                                Logger.WriteLine("Setting up nextPeerSocket to " + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Address + ":" + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Port);

                                response = Message.CreateMessageRoomModel(Room);
                                nextPeerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);
                                Logger.WriteLine("Send room info");
                            }
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.RoomModel)
                    {
                        #region Room
                        Logger.WriteLine("RoomModel");
                        Room room;
                        request.GetRoomModel(out room);
                        Room = room;
                        #endregion
                    }
                    else if (requestType == Message.MessageType.Quit)
                    {
                        int peerId;
                        request.GetQuit(out peerId);
                        Peer peer = Room.Members.Find(fpeer => fpeer.PeerId == peerId);
                        byte[] bufferRecv;

                        if (Room.Members.Count != 2)
                        {
                            if (PeerId == peerId)
                            {
                                Logger.WriteLine("Quit done");
                            }
                            else
                            {
                                int i = 0;
                                for (; i < Room.Members.Count; i++)
                                {// i adalah indeks peer yang ingin quit
                                    if (Room.Members[i].PeerId == peerId)
                                    {
                                        break;
                                    }
                                }

                                int j = 0;
                                for (; j < Room.Members.Count; j++)
                                {// j adalah indeks current peer
                                    if (Room.Members[j].PeerId == PeerId)
                                    {
                                        break;
                                    }
                                }

                                if (j == i + 1 || (j == 0 && i == Room.Members.Count - 1)) // yg mau quit adalah peer sebelum current peer
                                {
                                    quit = true;
                                }

                                response = request;

                                lock (nextPeerPaddle)
                                {
                                    nextPeerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);
                                    Logger.WriteLine("Forward Quit to " + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Address);
                                    bufferRecv = new byte[1024];
                                    nextPeerSocket.Receive(bufferRecv, 0, bufferRecv.Length, SocketFlags.None);
                                }

                                if (i == j + 1 || (i == 0 && j == Room.Members.Count - 1))// yg mau quit adalah peer setelah current peer
                                {
                                    nextPeerSocket.Close();
                                    IPAddress ip = Room.Members[(i + 1) % (Room.Members.Count - 1)].IPAddress;
                                    IPEndPoint ipEndPoint = new IPEndPoint(ip, Room.Members[(i + 1) % (Room.Members.Count - 1)].ListeningPort);
                                    nextPeerSocket = new Socket(
                                        ip.AddressFamily,
                                        SocketType.Stream,
                                        ProtocolType.Tcp
                                        );

                                    nextPeerSocket.NoDelay = false;
                                    nextPeerSocket.Connect(ipEndPoint);

                                    nextPeerSocket = null;
                                }

                                if (this.PeerId == Room.Creator.PeerId || (peerId == Room.Creator.PeerId && Room.Members[1].PeerId == this.PeerId))
                                {
                                    lock (trackerPaddle)
                                    {
                                        response = Message.CreateMessageRemove(peerId, PeerId, Configuration.ListenPort, Room.RoomId);
                                        trackerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);

                                        bufferRecv = new byte[1024];
                                        trackerSocket.Receive(bufferRecv, 0, bufferRecv.Length, SocketFlags.None);
                                    }
                                }

                                if (peerId == Room.Creator.PeerId)
                                {
                                    Room.Creator = Room.Members[1];
                                }

                                response = Message.CreateMessageSuccess();
                                handler.Send(response.data, 0, response.data.Length, SocketFlags.None);

                                bufferRecv = new byte[1024];
                                nextPeerSocket.Receive(bufferRecv, 0, bufferRecv.Length, SocketFlags.None);
                            }
                        }
                        else
                        {
                            lock (trackerPaddle)
                            {
                                response = Message.CreateMessageRemove(peerId, PeerId, Configuration.ListenPort, Room.RoomId);
                                trackerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);

                                bufferRecv = new byte[1024];
                                trackerSocket.Receive(bufferRecv, 0, bufferRecv.Length, SocketFlags.None);
                            }
                        }
                        Room.Members.Remove(peer);
                    }
                    else if (requestType == Message.MessageType.Start)
                    {
                        #region Start
                        Logger.WriteLine("Start");
                        int peerId;
                        string roomId;
                        request.GetStart(out peerId, out roomId);

                        Logger.WriteLine("Received START message with PeerId : " + peerId + " RoomId : " + roomId);

                        if (peerId == PeerId)
                        {
                            // do nothing
                            Logger.WriteLine("FINISHED");
                        }
                        else
                        {
                            // Send NewMember message to next peer
                            response = request;
                            nextPeerSocket.Send(response.data, 0, response.data.Length, SocketFlags.None);
                            Logger.WriteLine("Forward START to " + (nextPeerSocket.RemoteEndPoint as IPEndPoint).Address);
                        }
                    }
                    else
                    {
                        Logger.WriteLine("Listener receive unknown message");
                        // Send FAILED message akibat ruang penuh
                        response = Message.CreateMessageFailed();
                        handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                    }
                        #endregion
                }

                if (!quit)
                {
                    IAsyncResult nextAsyncResult = handler.BeginReceive(
                        buffer,
                        0,
                        buffer.Length,
                        SocketFlags.None,
                        new AsyncCallback(ReceiveCallback),
                        obj
                    );

                    if (!nextAsyncResult.AsyncWaitHandle.WaitOne(Configuration.MaxTimeout))
                    {
                        Logger.WriteLine("Connection timeout for peer with IP Address " + (handler.LocalEndPoint as IPEndPoint).Address + ":" + (handler.LocalEndPoint as IPEndPoint).Port + " -> " + (handler.RemoteEndPoint as IPEndPoint).Address + ":" + (handler.RemoteEndPoint as IPEndPoint).Port);
                        Logger.WriteLine("Closing connection " + (handler.RemoteEndPoint as IPEndPoint).Address + ":" + (handler.RemoteEndPoint as IPEndPoint).Port);
                        handler.Close();
                    }
                }
            }
            catch (SocketException exc)
            {
                Logger.WriteLine(exc);
                if (exc.SocketErrorCode == SocketError.HostDown || exc.SocketErrorCode == SocketError.ConnectionReset)
                {
                    if (Room.Members.Count > 2)
                    {
                        int index = -1;
                        for (int i = 0; i < Room.Members.Count; i++)
                        {
                            Peer p = Room.Members[i];
                            if (p.IPAddress.Equals((handler.LocalEndPoint as IPEndPoint).Address))
                            {
                                index = i;
                            }
                        }

                        if (index == 0)
                        {
                            index = Room.Members.Count - 2;
                        }
                        else
                        {
                            index--;
                        }

                        Peer backPeer = Room.Members[index];
                        byte[] buffer = new byte[1024];
                        Message request = Message.CreateMessageQuit(backPeer.PeerId);
                        lock (nextPeerPaddle)
                        {
                            nextPeerSocket.Send(request.data, 0, request.data.Length, SocketFlags.None);
                            nextPeerSocket.Receive(buffer, 0, buffer.Length, SocketFlags.None);
                        }
                    }
                    else
                    {
                        // Remove last element
                        Room.Members.RemoveAt(1);
                        lock (nextPeerPaddle)
                        {
                            nextPeerSocket = null;
                        }
                    }
                }
            }

            Logger.WriteLine();
        }
예제 #4
0
        public bool JoinRoom(string roomId)
        {
            try
            {
                if ((IsConnected) && (!IsInRoom))
                {
                    Logger.WriteLine("Requesting to join room " + roomId);
                    Message request = Message.CreateMessageJoin(PeerId, roomId);
                    byte[] buffer = new byte[1024];

                    lock (trackerPaddle)
                    {
                        trackerSocket.Send(request.data, 0, request.data.Length, SocketFlags.None);
                        trackerSocket.Receive(buffer, buffer.Length, SocketFlags.None);
                    }

                    Message response = new Message(buffer);
                    Message.MessageType responseType = response.GetMessageType();
                    if (responseType == Message.MessageType.CreatorInfo)
                    {
                        IPAddress ip;
                        int port;
                        response.GetCreatorInfo(out ip, out port);

                        Logger.WriteLine("GunbondPeer (Peer - Tracker): Creator Info");
                        Logger.WriteLine("Hostname : " + ip);
                        Logger.WriteLine("Port     : " + port);

                        SocketPermission permission = new SocketPermission(
                             NetworkAccess.Connect,
                             TransportType.Tcp,
                             "",
                             SocketPermission.AllPorts
                             );
                        permission.Demand();

                        byte[] bufferFromCreator = new byte[1024];

                        lock (nextPeerPaddle)
                        {
                            IPEndPoint ipEndPoint = new IPEndPoint(ip, port);
                            nextPeerSocket = new Socket(
                                ip.AddressFamily,
                                SocketType.Stream,
                                ProtocolType.Tcp
                                );

                            nextPeerSocket.NoDelay = false;
                            nextPeerSocket.Connect(ipEndPoint);
                            Message messageConnectToCreator = Message.CreateMessageHandshakePeerCreator(PeerId, Configuration.ListenPort);

                            nextPeerSocket.Send(messageConnectToCreator.data, 0, messageConnectToCreator.data.Length, SocketFlags.None);
                            nextPeerSocket.Receive(bufferFromCreator, bufferFromCreator.Length, SocketFlags.None);
                        }

                        keepAliveRoom = new Thread(new ThreadStart(SendAliveNextPeer));
                        keepAliveRoom.Start();

                        Message messageFromCreator = new Message(bufferFromCreator);
                        Message.MessageType fromCreatorMessageType = messageFromCreator.GetMessageType();
                        if (fromCreatorMessageType == Message.MessageType.Success)
                        {
                            IsInRoom = true;
                            IsCreator = false;

                            Logger.WriteLine("Successfully joined room.");
                            return true;
                        }
                        else
                        {
                            Logger.WriteLine("Request join room failed 1.");
                            return false;
                        }

                    }
                    else if (responseType == Message.MessageType.Failed)
                    {
                        Console.WriteLine("Request join room failed 2.");
                        return false;
                    }
                    else
                    {
                        Console.WriteLine("Response unrecognized.");
                        return false;
                    }
                }
                else if (!IsConnected)
                {
                    Console.WriteLine("Not connected to tracker, connect to tracker first.");
                    return false;
                }
                else if (IsInRoom)
                {
                    Console.WriteLine("Currently in room, quit room first.");
                    return false;
                }
                else
                {
                    Console.WriteLine("Unknown error.");
                    return false;
                }
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.ToString());
                return false;
            }
        }
예제 #5
0
        public List<Message.MessageRoomBody> ListRooms()
        {
            try
            {
                Logger.WriteLine("Requesting to list room");

                Message messageOut = Message.CreateMessageList(PeerId);
                byte[] buffer = new byte[1024];

                trackerSocket.Send(messageOut.data, 0, messageOut.data.Length, SocketFlags.None);
                trackerSocket.Receive(buffer, 0, buffer.Length, SocketFlags.None);

                Message messageIn = new Message(buffer);
                if (messageIn.GetMessageType() == Message.MessageType.Room)
                {
                    List<Message.MessageRoomBody> s;
                    messageIn.GetRoom(out s);
                    foreach (var a in s)
                    {
                        Logger.WriteLine("ROOM: " + a.roomId);
                    }
                    return s;
                }
                else
                {
                    Logger.WriteLine("Failed to list rooms");
                    return null;
                }
            }
            catch (Exception exc)
            {
                Logger.WriteLine(exc);
                return null;
            }
        }
예제 #6
0
        public bool ConnectTracker()
        {
            try
            {
                if (!IsConnected)
                {
                    SocketPermission permission = new SocketPermission(
                        NetworkAccess.Connect,
                        TransportType.Tcp,
                        "",
                        SocketPermission.AllPorts
                        );

                    permission.Demand();

                    IPAddress trackerAddr;
                    if (IPAddress.TryParse(Configuration.TrackerAddress, out trackerAddr))
                    {
                        byte[] buffer = new byte[1024];
                        lock (trackerPaddle)
                        {
                            IPEndPoint ipEndPoint = new IPEndPoint(trackerAddr, Configuration.Port);
                            trackerSocket = new Socket(
                                trackerAddr.AddressFamily,
                                SocketType.Stream,
                                ProtocolType.Tcp
                               );

                            trackerSocket.NoDelay = false;
                            trackerSocket.Connect(ipEndPoint);
                            Message request = Message.CreateMessageHandshakePeer();

                            trackerSocket.Send(request.data, 0, request.data.Length, SocketFlags.None);
                            trackerSocket.Receive(buffer, buffer.Length, SocketFlags.None);
                        }

                        Message response = new Message(buffer);
                        if (response.GetMessageType() == Message.MessageType.HandshakeTracker)
                        {
                            int peerId;
                            response.GetHandshakeTracker(out peerId);
                            PeerId = peerId;
                            IsConnected = true;
                            Logger.WriteLine("Connection to tracker is successfully established. PeerID: " + PeerId);

                            IPAddress ipAddr = (trackerSocket.LocalEndPoint as IPEndPoint).Address;
                            IPEndPoint ipEndPointListener = new IPEndPoint(ipAddr, Configuration.ListenPort);
                            SocketPermission permissionListener = new SocketPermission(NetworkAccess.Accept, TransportType.Tcp, "", Configuration.ListenPort);

                            listenerSocket = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                            listenerSocket.Bind(ipEndPointListener);

                            permission.Demand();

                            waitPeer = new Thread(new ParameterizedThreadStart(WaitPeer));
                            waitPeer.Start(4);

                            keepAlive = new Thread(new ThreadStart(SendAliveTracker));
                            keepAlive.Start();
                            return true;
                        }
                        else
                        {
                            Logger.WriteLine("Failed to connect to tracker.");
                            return false;
                        }
                    }
                    else
                    {
                        Logger.WriteLine("Failed to connect, tracker not found.");
                        return false;
                    }
                }
                else
                {
                    Logger.WriteLine("Already connected to tracker.");
                    return false;
                }
            }
            catch (SocketException exc)
            {
                Logger.WriteLine(exc);
                return false;
            }
        }
예제 #7
0
        public bool CreateRoom(string roomId, int maxPlayers)
        {
            try
            {
                if (IsConnected && !IsInRoom)
                {
                    Logger.WriteLine("Requesting to create room");

                    byte[] buffer = new byte[1024];
                    Message request = Message.CreateMessageCreate(PeerId, maxPlayers, roomId, Configuration.ListenPort);

                    lock (trackerPaddle)
                    {
                        trackerSocket.Send(request.data, 0, request.data.Length, SocketFlags.None);
                        trackerSocket.Receive(buffer, buffer.Length, SocketFlags.None);
                    }

                    Message response = new Message(buffer);
                    Message.MessageType responseType = response.GetMessageType();
                    if (responseType == Message.MessageType.Success)
                    {
                        Logger.WriteLine("Request create room success: " + roomId);

                        Room = new Room(roomId, new Peer(PeerId, (trackerSocket.LocalEndPoint as IPEndPoint).Address, Configuration.ListenPort), maxPlayers);
                        Room.Members.Add(Room.Creator);

                        IsInRoom = true;
                        IsCreator = true;

                        return true;
                    }
                    else if (responseType == Message.MessageType.Failed)
                    {
                        Logger.WriteLine("Request create room failed.");
                        return false;
                    }
                    else
                    {
                        Logger.WriteLine("Response unrecognized.");
                        return false;
                    }
                }
                else if (!IsConnected)
                {
                    Logger.WriteLine("Not connected to tracker, connect to tracker first.");
                    return false;
                }
                else if (IsInRoom)
                {
                    Logger.WriteLine("Currently in room, quit room first.");
                    return false;
                }
                else
                {
                    Logger.WriteLine("Unknown error.");
                    return false;
                }
            }
            catch (Exception exc)
            {
                Logger.WriteLine(exc);
                return false;
            }
        }
예제 #8
0
        private void Start(Message m)
        {
            isStart = true;

            int peerId;
            String roomId;
            List<int> teamA;
            List<int> teamB;

            m.GetStart(out peerId, out roomId, out teamA, out teamB);

            foreach (var x in teamA)
            {
                this.teamA.Add(Game1.main_console.Room.Members.Find(f => f.PeerId == x));
            }

            foreach (var x in teamB)
            {
                this.teamB.Add(Game1.main_console.Room.Members.Find(f => f.PeerId == x));
            }
        }
예제 #9
0
        public void ReceiveCallback(IAsyncResult target)
        {
            try
            {
                object[] obj = new object[2];
                obj = (object[])target.AsyncState;

                byte[] data = (byte[])obj[0];
                Socket handler = (Socket)obj[1];
                IPAddress tempIP = (handler.RemoteEndPoint as IPEndPoint).Address;

                string content = string.Empty;
                int bytesRead = handler.EndReceive(target);

                if (bytesRead > 0)
                {
                    Message request = new Message(data);
                    Message response;

                    Message.MessageType requestType = request.GetMessageType();
                    if (requestType == Message.MessageType.HandshakePeer)
                    {
                        #region Handshake
                        Logger.WriteLine("New peer with IP Address " + (handler.RemoteEndPoint as IPEndPoint).Address.ToString() + " request handshake.");

                        if (peers.Count < Configuration.MaxPeer)
                        {
                            int newPeerId = GenerateNewPeerId();
                            Peer peer = new Peer(newPeerId, (handler.RemoteEndPoint as IPEndPoint).Address);
                            peers.Add(newPeerId, peer);

                            Logger.WriteLine("Peer with IP Address " + (handler.RemoteEndPoint as IPEndPoint).Address.ToString() + " registered with ID " + newPeerId + ".");
                            Logger.WriteLine(peer);
                            Logger.WriteLine();

                            // send handshake response with ID
                            response = Message.CreateMessageHandshakeTracker(newPeerId);
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        else
                        {
                            // send handshake response with ID
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.KeepAlive)
                    {
                        #region Keep Alive
                        int peerId;
                        Peer peer;
                        request.GetKeepAlive(out peerId);
                        if (peers.TryGetValue(peerId, out peer))
                        {
                            Logger.WriteLine("Keep alive is sent by Peer: " + peer);

                            // send KEEP ALIVE message back
                            response = request;
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        else
                        {
                            // send FAIL message that peer is not registered
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.CreateRoom)
                    {
                        #region Create Room
                        int peerId, maxPlayers, listenPort;
                        string roomId;
                        request.GetCreate(out peerId, out maxPlayers, out roomId, out listenPort);

                        Peer peer;
                        if (peers.TryGetValue(peerId, out peer))
                        {
                            Room room;
                            if (!rooms.TryGetValue(roomId, out room))
                            {
                                room = new Room(roomId, peer, maxPlayers, listenPort);
                                rooms.Add(roomId, room);
                                Logger.WriteLine("Create room request is sent by peer " + peer + " for room " + room);

                                // send reply message SUCCESS
                                response = Message.CreateMessageSuccess();
                                handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                            }
                            else
                            {
                                // send message FAIL that room doesn't exist
                                response = Message.CreateMessageFailed();
                                handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                            }
                        }
                        else
                        {
                            // send message FAIL that peer is not registered
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.ListRoom)
                    {
                        #region List Room
                        int peerId;
                        request.GetList(out peerId);

                        Peer peer;
                        if (peers.TryGetValue(peerId, out peer) && !peer.InRoom)
                        {
                            Logger.WriteLine("List room is sent to Peer " + peer);
                            List<Message.MessageRoomBody> listRooms = new List<Message.MessageRoomBody>();
                            foreach (var r in rooms.Values)
                            {
                                Message.MessageRoomBody mb;
                                mb.roomId = r.Id;
                                mb.maxPlayers = r.MaxPlayers;
                                mb.currentPlayer = r.Members.Count;
                                listRooms.Add(mb);
                            }

                            // send ROOM message
                            response = Message.CreateMessageRoom(listRooms);
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        else
                        {
                            // send message FAIL that peer is not registered
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.Join)
                    {
                        #region Join Room
                        int peerId;
                        string roomId;
                        request.GetJoin(out peerId, out roomId);
                        Peer peer;
                        if (peers.TryGetValue(peerId, out peer) && !peer.InRoom)
                        {
                            Room room;
                            if (rooms.TryGetValue(roomId, out room) && room.Members.Count < room.MaxPlayers)
                            {
                                Logger.WriteLine("Join room request is sent by Peer " + peer + " for Room " + room);

                                // send IP address back to peer
                                response = Message.CreateMessageCreatorInfo(room.Creator.IpAddress, room.ListenPort);
                                handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                            }
                            else
                            {
                                // send message FAIL that peer is not registered
                                response = Message.CreateMessageFailed();
                                handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                            }
                        }
                        else
                        {
                            // send message FAIL that peer is not registered
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.Start)
                    {
                        #region Start
                        int peerId;
                        request.GetList(out peerId);
                        Peer peer;
                        if (peers.TryGetValue(peerId, out peer) && !peer.InRoom)
                        {

                        }
                        else
                        {
                            // send message FAIL that peer is not registered
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.Quit)
                    {
                        #region Quit
                        int peerId;
                        request.GetList(out peerId);
                        Peer peer;
                        if (peers.TryGetValue(peerId, out peer) && !peer.InRoom)
                        {

                        }
                        else
                        {
                            // send message FAIL that peer is not registered
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion

                        //}
                        //else if (requestType == Message.MessageType.Add)
                        //{
                        //    #region Add
                        //    int peerId;
                        //    request.GetList(out peerId);
                        //    Peer peer;
                        //    if (peers.TryGetValue(peerId, out peer) && !peer.InRoom)
                        //    {
                        //        // ...
                        //    }
                        //    else
                        //    {
                        //        // send message FAIL that peer is not registered
                        //        response = Message.CreateMessageFailed();
                        //        handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        //    }
                        //    #endregion
                    }
                    else if (requestType == Message.MessageType.Add)
                    {
                        #region Add
                        int peerId;
                        string roomId;
                        request.GetAdd(out peerId, out roomId);
                        Peer peer;
                        Room room;
                        if (peers.TryGetValue(peerId, out peer) && (rooms.TryGetValue(roomId, out room)))
                        {
                            room.AddPeer(peer);
                            response = Message.CreateMessageSuccess();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        else
                        {
                            // send message FAIL that peer is not registered
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else if (requestType == Message.MessageType.Remove)
                    {
                        #region Remove
                        int peerId;
                        int creatorId;
                        int creatorPort;
                        string roomId;

                        request.GetRemove(out peerId, out creatorId, out creatorPort, out roomId);
                        Room room;
                        if (rooms.TryGetValue(roomId, out room))
                        {
                            room.RemovePeer(peerId);
                            Peer creator;
                            room.Members.TryGetValue(creatorId, out creator);
                            room.Creator = creator;
                            room.ListenPort = creatorPort;

                            response = Message.CreateMessageSuccess();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        else
                        {
                            // send message FAIL that peer is not registered
                            response = Message.CreateMessageFailed();
                            handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                        }
                        #endregion
                    }
                    else
                    {
                        Logger.WriteLine("Unknown message received from " + (handler.RemoteEndPoint as IPEndPoint));
                        // throw message failed
                        response = Message.CreateMessageFailed();
                        handler.Send(response.data, 0, response.data.Length, SocketFlags.None);
                    }

                    #region Receive for Next Message
                    byte[] buffer = new byte[1024];
                    obj = new object[2];
                    obj[0] = buffer;
                    obj[1] = handler;
                    IAsyncResult nextAsyncResult = handler.BeginReceive(
                        buffer,
                        0,
                        buffer.Length,
                        SocketFlags.None,
                        new AsyncCallback(ReceiveCallback),
                        obj
                        );

                    if (!nextAsyncResult.AsyncWaitHandle.WaitOne(Configuration.MaxTimeout))
                    {
                        Logger.WriteLine("Connection timeout for peer with IP Address " + (handler.LocalEndPoint as IPEndPoint).Address + ":" + (handler.LocalEndPoint as IPEndPoint).Port + " -> " + (handler.RemoteEndPoint as IPEndPoint).Address + ":" + (handler.RemoteEndPoint as IPEndPoint).Port);

                        // find peer id
                        int peerId = 0;
                        foreach (KeyValuePair<int, Peer> entry in peers)
                        {
                            if (entry.Value.IpAddress.Equals((handler.RemoteEndPoint as IPEndPoint).Address))
                            {
                                peerId = entry.Key;
                                break;
                            }
                        }
                        peers.Remove(peerId);

                        handler.Close();
                    }
                    #endregion
                }
            }
            catch (SocketException exc)
            {
                Logger.WriteLine(exc);
            }
        }
예제 #10
0
        private void ProcessMessages(Message msg)
        {
            Logger.WriteLine("MAAAAAAAAASSSSSSSSSUU");
            float xPos; // x position
            float yPos; // y position
            float power; // power
            float angle; // angle
            float life; // damage

            bool isRocketFlying;
            int PeerID;
            msg.GetMessageGame(out xPos, out yPos, out angle, out power, out life, out isRocketFlying, out PeerID);

            currentPlayer.Position.X = xPos;
            currentPlayer.Position.Y = yPos;
            currentPlayer.Power = power;
            currentPlayer.Angle = angle;
            rocketFlying = isRocketFlying;
            //rocketDamage = damage;
            currentPlayer.Health = life;

            if (isRocketFlying)
            {
                rocketPosition = currentPlayer.Position;
                rocketPosition.X += 20;
                rocketPosition.Y -= 10;
                rocketAngle = currentPlayer.Angle;
                Vector2 up = new Vector2(0, -1);
                Matrix rotMatrix = Matrix.CreateRotationZ(rocketAngle);
                rocketDirection = Vector2.Transform(up, rotMatrix);
                rocketDirection *= currentPlayer.Power / 50.0f;
            }

            Logger.WriteLine("-----------------");
            Logger.WriteLine("players" + currentPlayer + PeerID);
            Logger.WriteLine(currentPlayer.Position.X);
            Logger.WriteLine(currentPlayer.Position.Y);
            Logger.WriteLine(currentPlayer.Power);
            Logger.WriteLine(currentPlayer.Angle);
            Logger.WriteLine("Rocket status:" + isRocketFlying);
            Logger.WriteLine(currentPlayer.Health);
            Logger.WriteLine("-----------------");
        }
예제 #11
0
        private void SendAliveTracker()
        {
            try
            {
                while (true)
                {
                    Logger.WriteLine("SendAliveTracker");
                    Message mes = Message.CreateMessageKeepAlive(PeerId);
                    byte[] buffer = new byte[1024];

                    lock (trackerPaddle)
                    {
                        trackerSocket.Send(mes.data, 0, mes.data.Length, SocketFlags.None);
                        trackerSocket.Receive(buffer, 0, buffer.Length, SocketFlags.None);
                    }

                    Message response = new Message(buffer);
                    if (response.GetMessageType() == Message.MessageType.KeepAlive)
                    {
                        Logger.WriteLine("KeepAlive success.");
                        Thread.Sleep(Configuration.MaxTimeout / 10);
                    }
                    else
                    {
                        Logger.WriteLine("Message KeepAlive has not been received.");
                    }
                    Logger.WriteLine();
                }
            }
            catch (Exception)
            {
                lock (trackerPaddle)
                {
                    if (trackerSocket == null)
                    {
                        Logger.WriteLine("Connection terminated");
                        IsConnected = false;
                    }
                }
            }
        }
예제 #12
0
        public static Message CreateMessageRoom(List<MessageRoomBody> rooms)
        {
            int mbSize = 0;
            if (rooms.Count > 0)
            {
                mbSize = Marshal.SizeOf(rooms[0]);
            }

            byte[] data = new byte[20 + 4 + rooms.Count * mbSize];
            FillHeader(data);
            data[19] = 200;

            byte[] id = ConvertIntToBytes(rooms.Count);
            data[20] = id[0];
            data[21] = id[1];
            data[22] = id[2];
            data[23] = id[3];

            int j = 24;
            for (int i = 0; i < rooms.Count; i++)
            {
                byte[] temp = GetBytes(rooms[i]);
                Buffer.BlockCopy(temp, 0, data, j, mbSize);
                j += mbSize;
            }

            Message m = new Message();
            m.data = data;
            return m;
        }
예제 #13
0
        public static Message CreateMessageHandshakeTracker(int peerId)
        {
            byte[] data = new byte[24];
            FillHeader(data);
            data[19] = 136;

            byte[] id = ConvertIntToBytes(peerId);
            data[20] = id[0];
            data[21] = id[1];
            data[22] = id[2];
            data[23] = id[3];

            Message m = new Message();
            m.data = data;
            return m;
        }
예제 #14
0
        public static Message CreateMessageGame(float x, float y, float angle, float power, float damage, bool isRocketFlying, int peerId)
        {
            byte[] data = new byte[45];
            FillHeader(data);

            //data[0..18] = 0 for FillHeader(data)

            //data[19] for Message Type
            data[19] = 123;

            // data[20..23] for X position
            byte[] temp0 = BitConverter.GetBytes(x);
            data[20] = temp0[0];
            data[21] = temp0[1];
            data[22] = temp0[2];
            data[23] = temp0[3];

            // data[24..27] for Y position
            byte[] temp = BitConverter.GetBytes(y);
            data[24] = temp[0];
            data[25] = temp[1];
            data[26] = temp[2];
            data[27] = temp[3];

            //data[28..31] for angle
            byte[] temp3 = BitConverter.GetBytes(angle);
            data[28] = temp3[0];
            data[29] = temp3[1];
            data[30] = temp3[2];
            data[31] = temp3[3];

            //data[32..35] for power
            byte[] temp4 = BitConverter.GetBytes(power);
            data[32] = temp4[0];
            data[33] = temp4[1];
            data[34] = temp4[2];
            data[35] = temp4[3];

            //data[36..39] for damage
            byte[] temp5 = BitConverter.GetBytes(damage);
            data[36] = temp5[0];
            data[37] = temp5[1];
            data[38] = temp5[2];
            data[39] = temp5[3];

            //data[40] for isRocketFlying
            data[40] = Convert.ToByte(isRocketFlying);

            // data[41..44] for peerId
            byte[] id = ConvertIntToBytes(peerId);
            data[41] = id[0];
            data[42] = id[1];
            data[43] = id[2];
            data[44] = id[3];

            Message m = new Message();
            m.data = data;
            return m;
        }