public override void Update()
        {
            if (this.Active)
            {
                this.Position += Velocity;
                m_LifeTick    += TICK;

                if (m_LifeTick > 2.0f)
                {
                    m_LifeTick    = 0.0f;
                    this.Active   = false;
                    this.Velocity = Vector2.Zero;
                }

                // Check Collisions
                foreach (GameObject go in m_CollisionObjects)
                {
                    if (go.Active)
                    {
                        if (this.Bounds().Intersects(go.Bounds()))
                        {
                            go.Active = false;

                            // If this object is not set to update and send out packets every frame then can force it here as they need to know its not active
                            if (!go.IsUpdatable())
                            {
                                PacketDefs.PlayerInputUpdatePacket updatePacket = new PacketDefs.PlayerInputUpdatePacket(
                                    go.UnqId(), go.Position.X, go.Position.Y, go.FrameX(), go.FrameY(), go.Active);
                                ServerManager.instance.SendAllUdp(fastJSON.JSON.ToJSON(
                                                                      updatePacket, PacketDefs.JsonParams()));
                            }

                            this.Active = false;

                            // Add exp for killimg enemy
                            GameClient client = ServerManager.instance.GetClient(InvokedBy);
                            if (client != null)
                            {
                                client.localExpCache += 2;

                                // Send TCP pack with new exp update, note* only hit the database to increment exp when the level is finished
                                PacketDefs.UpdateExpPacket flp = new PacketDefs.UpdateExpPacket(client.localExpCache, PacketDefs.ID.OUT_TCP_ExpQueery);
                                ServerManager.instance.SendTcp(client.tcpSocket, fastJSON.JSON.ToJSON(flp, PacketDefs.JsonParams()));
                            }
                        }
                    }
                }
            }
        }
        private void Dead()
        {
            m_MillisPerFrame = 0.07f;
            frameX           = 0;// 7;
            Position         = Player.SpawnPosition();
            Velocity         = Vector2.Zero;
            m_Health         = MAX_HEALTH;
            m_Hurt           = false;
            m_Dying          = false;
            m_HurtCounter    = 0.0f;

            // Send UDP pack with new health
            PacketDefs.PlayerHealthPacket hp = new PacketDefs.PlayerHealthPacket(m_Health);
            ServerManager.instance.SendUdp(m_ClientId,
                                           fastJSON.JSON.ToJSON(hp, PacketDefs.JsonParams()));
        }
        private void AcceptCallback(IAsyncResult ar)
        {
            allDone.Set();

            // ---- Set up tcp socket ----
            Socket listener = (Socket)ar.AsyncState;
            Socket localTcp = listener.EndAccept(ar);

            // ---- Generate a state object to pass around Async calls ----
            TcpStateObject tcpStateObj = new TcpStateObject();

            tcpStateObj.tcpSocket = localTcp;

            // ---- Add a new client with this Tcp socket and get the hash ----
            int hash = m_ServerManager.AddNewClient(tcpStateObj.tcpSocket);

            // ---- Gen a Udp state object on free system port----
            IPEndPoint localUpdEndPt = new IPEndPoint(IPAddress.Parse(ServerDefs.GetLocalIPAddress()), 0);
            UdpClient  localUdp      = new UdpClient(localUpdEndPt);

            UdpStateObject udpStateObj = new UdpStateObject();

            udpStateObj.endPoint  = localUpdEndPt;
            udpStateObj.udpSocket = localUdp;

            // Resolve system generated port of local udp socket
            int port = ((IPEndPoint)localUdp.Client.LocalEndPoint).Port;

            Logger.Log(string.Format("Listening for UDP connection on port {0}", port));

            // Store this in client data
            m_ServerManager.SetLocalUdpPort(hash, port);

            // **Important -- SEND Register Function and give them their id which they must store, and use in all packets so we know who they are, also send them local udp port that we are listening for them on.
            m_ServerManager.SendTcp(tcpStateObj.tcpSocket, fastJSON.JSON.ToJSON(new PacketDefs.connectPacket(hash, port), PacketDefs.JsonParams()));

            // ---- Begin Async Tcp receive for this client
            tcpStateObj.tcpSocket.BeginReceive(tcpStateObj.buffer, 0,
                                               ServerDefs.BUFF_SIZE, 0,
                                               new AsyncCallback(TcpReadCallback), tcpStateObj
                                               );

            // ----  The client knows this local udp port, so if/when we get a message from them on this, we can add their end
            //		 point to the client hash table and connect a local udp Socket to that end point which is also stored and
            //		 completes the data structure for this client
            localUdp.BeginReceive(new AsyncCallback(UdpInitialReadCallback), udpStateObj);

            Logger.Log("New client connected to server");
            Logger.Log(string.Format("Number of clients connected {0}.\nNew client TCP Endpoint {1}.\nWaiting for udp connection on port {2}",
                                     m_ServerManager.NumClients(), localTcp.RemoteEndPoint, port));
        }
        private void CheckCollisions()
        {
            // ---- Resolve collision ----
            bool contactLeft = false, contactRight = false, contactYbottom = false, contactYtop = false;

            Vector2 predicted_speed = this.Velocity;;
            float   projectedMoveX, projectedMoveY, originalMoveX, originalMoveY;

            originalMoveX = predicted_speed.X;
            originalMoveY = predicted_speed.Y;

            // This needs to be from the qyadtree
            foreach (GameObject colTest in GameSimulation.instance.GetObjects())
            {
                if ((colTest.TypeId() == GameObjectType.Wall || colTest.TypeId() == GameObjectType.DestructablePlatform) && colTest.Active)
                {
                    for (int dir = 0; dir < 4; dir++)
                    {
                        if (dir == UP && predicted_speed.Y > 0)
                        {
                            continue;
                        }
                        if (dir == DOWN && predicted_speed.Y < 0)
                        {
                            continue;
                        }
                        if (dir == LEFT && predicted_speed.X > 0)
                        {
                            continue;
                        }
                        if (dir == RIGHT && predicted_speed.X < 0)
                        {
                            continue;
                        }

                        projectedMoveX = (dir >= LEFT ? predicted_speed.X : 0);
                        projectedMoveY = (dir < LEFT ? predicted_speed.Y : 0);

                        while ((colTest.Bounds().Contains(this.points[dir * 2].X + (int)this.Position.X + (int)projectedMoveX,
                                                          this.points[dir * 2].Y + (int)this.Position.Y + (int)projectedMoveY)
                                ||
                                colTest.Bounds().Contains(this.points[dir * 2 + 1].X + (int)this.Position.X + (int)projectedMoveX,
                                                          this.points[dir * 2 + 1].Y + (int)this.Position.Y + (int)projectedMoveY)))
                        {
                            if (dir == UP)
                            {
                                projectedMoveY++;
                            }
                            if (dir == DOWN)
                            {
                                projectedMoveY--;
                            }
                            if (dir == LEFT)
                            {
                                projectedMoveX++;
                            }
                            if (dir == RIGHT)
                            {
                                projectedMoveX--;
                            }
                        }

                        if (dir >= LEFT && dir <= RIGHT)
                        {
                            predicted_speed.X = projectedMoveX;
                        }
                        if (dir >= UP && dir <= DOWN)
                        {
                            predicted_speed.Y = projectedMoveY;
                        }
                    }

                    // Resolve contact
                    if (predicted_speed.Y > originalMoveY && originalMoveY < 0)
                    {
                        contactYtop = true;
                    }

                    if (predicted_speed.Y < originalMoveY && originalMoveY > 0)
                    {
                        contactYbottom = true;
                    }

                    if (predicted_speed.X - originalMoveX < -0.01f)
                    {
                        contactRight = true;
                    }

                    if (predicted_speed.X - originalMoveX > 0.01f)
                    {
                        contactLeft = true;
                    }

                    // Resolve collision from contact
                    if (contactYbottom)
                    {
                        this.Velocity.Y = 0;
                        this.Grounded   = true;
                    }
                    else if (contactYtop)
                    {
                        this.Velocity.Y = 0;
                    }

                    if (contactLeft || contactRight)
                    {
                        this.Velocity.X = 0;
                    }
                }
                else if (colTest.TypeId() == GameObjectType.Exit)
                {
                    if (this.Bounds().Intersects(colTest.Bounds()))
                    {
                        // Stop updating this object
                        Active = false;

                        // Send Back to previous position
                        this.Position = Player.SpawnPosition();
                        this.Velocity = Vector2.Zero;

                        GameClient client = ServerManager.instance.GetClient(m_ClientId);
                        if (client != null)
                        {
                            client.inGame = false;

                            // NOTE** This is the only time we want to update the database (when they finish the level)
                            client.localExpCache += 30;

                            // Give this client some experience on database
                            ServerManager.instance.UpdateClientExpDB(client.userName, client.localExpCache);

                            // Send him back to the lobby : TODO Get EXP from DB
                            PacketDefs.UpdateExpPacket flp = new PacketDefs.UpdateExpPacket(client.localExpCache, PacketDefs.ID.OUT_TCP_FinishLevel);
                            ServerManager.instance.SendTcp(client.tcpSocket, fastJSON.JSON.ToJSON(flp, PacketDefs.JsonParams()));

                            if (!GameSimulation.instance.ArePeopleInGame())
                            {
                                // No one is in-game so clear data
                                GameSimulation.instance.ScheduleClearGameData();
                                return;
                            }
                        }
                    }
                }
                else if (colTest.TypeId() == GameObjectType.GoldSkull)
                {
                    if (this.Bounds().Intersects(colTest.Bounds()) && colTest.Active)
                    {
                        colTest.Active = false;

                        // Send out a packet here informing them it's deactivated (rather than using standward way and doing it every frame)
                        PacketDefs.PlayerInputUpdatePacket updatePacket = new PacketDefs.PlayerInputUpdatePacket(
                            colTest.UnqId(), colTest.Position.X, colTest.Position.Y, colTest.FrameX(), colTest.FrameY(), colTest.Active);
                        ServerManager.instance.SendAllUdp(fastJSON.JSON.ToJSON(
                                                              updatePacket, PacketDefs.JsonParams()));

                        // Add exp for collecting skull
                        GameClient client = ServerManager.instance.GetClient(m_ClientId);
                        if (client != null)
                        {
                            client.localExpCache += 10;

                            // Send TCP pack with new exp update, note* only hit the database to increment exp when the level is finished
                            PacketDefs.UpdateExpPacket flp = new PacketDefs.UpdateExpPacket(client.localExpCache, PacketDefs.ID.OUT_TCP_ExpQueery);
                            ServerManager.instance.SendTcp(client.tcpSocket, fastJSON.JSON.ToJSON(flp, PacketDefs.JsonParams()));
                        }
                    }
                }
                else if (IsHazard(colTest.TypeId()))
                {
                    if (!m_Hurt)
                    {
                        if (this.Bounds().Intersects(colTest.Bounds()) && colTest.Active)
                        {
                            //if (Math.Abs(Velocity.X) >= 1.0f)
                            //{
                            Velocity = new Vector2(-(float)m_Facing * 10, -20);
                            //}
                            //else
                            //{
                            //  Velocity.Y = -30.0f;
                            //}

                            m_Hurt    = true;
                            Grounded  = true;
                            m_Health -= 1;

                            // Send UDP pack with new health
                            PacketDefs.PlayerHealthPacket hp = new PacketDefs.PlayerHealthPacket(m_Health);
                            ServerManager.instance.SendUdp(m_ClientId, fastJSON.JSON.ToJSON(hp, PacketDefs.JsonParams()));
                        }
                    }
                }
            }
        }
Example #5
0
        // ---- Function Pointers ----
        private bool CreateAccountMsg(Dictionary <string, object> json)
        {
            Logger.Log("Got Create account message");

            // Data to extract form this packet
            string name     = "";
            string password = "";
            int    clientId = -1;

            // Extract the id of the sender
            if (json.ContainsKey("id"))
            {
                clientId = (int)((long)json["id"]);
            }
            else
            {
                Logger.Log("Error Parsing client id in start game packet", Logger.LogPrio.Error);
                return(false);
            }

            if (json.ContainsKey("userName"))
            {
                name = (string)json["userName"];
            }

            if (json.ContainsKey("password"))
            {
                password = (string)json["password"];
            }

            // Send Packet with the return value of AddnewUserToDatabase as the argument for success
            PacketDefs.msgPacket returnPack = new PacketDefs.msgPacket();

            if (string.IsNullOrEmpty(name))
            {
                returnPack.msg = "Error: Name is null or empty";
            }
            else if (string.IsNullOrEmpty(password))
            {
                returnPack.msg = "Error: Password is null or empty";
            }
            else
            {
                returnPack.msg = ServerManager.instance.AddNewClientToDatabase(clientId, name, password);
            }

            ServerManager.instance.SendTcp(ServerManager.instance.GetClient(clientId).tcpSocket, fastJSON.JSON.ToJSON(returnPack, PacketDefs.JsonParams()));

            return(true);
        }
Example #6
0
        private bool LeaderboardRequestMsg(Dictionary <string, object> json)
        {
            // Just send them back the request
            int clientId = -1;

            if (json.ContainsKey("id"))
            {
                clientId = (int)((long)json["id"]);
            }

            GameClient client = ServerManager.instance.GetClient(clientId);

            if (client != null)
            {
                PacketDefs.LeaderboardPacket lbp = new PacketDefs.LeaderboardPacket(ServerManager.instance.GetLeaderBoard());
                ServerManager.instance.SendTcp(ServerManager.instance.GetClient(clientId).tcpSocket, fastJSON.JSON.ToJSON(lbp, PacketDefs.JsonParams()));
                return(true);
            }

            return(false);
        }
Example #7
0
        private bool ExpQueeryMsg(Dictionary <string, object> json)
        {
            // Just send them back the request
            int clientId = -1;

            if (json.ContainsKey("id"))
            {
                clientId = (int)((long)json["id"]);
            }

            GameClient client = ServerManager.instance.GetClient(clientId);

            if (client != null)
            {
                PacketDefs.UpdateExpPacket flp = new PacketDefs.UpdateExpPacket(ServerManager.instance.GetClientExp(client.userName), PacketDefs.ID.OUT_TCP_ExpQueery);
                ServerManager.instance.SendTcp(ServerManager.instance.GetClient(clientId).tcpSocket, fastJSON.JSON.ToJSON(flp, PacketDefs.JsonParams()));
                return(true);
            }

            return(false);
        }
Example #8
0
        private bool StartGameMsg(Dictionary <string, object> json)
        {
            // This is complicated so will do my best to comment, even for myself in the future
            // There are 4 players allowed to drop in/out per game, this tries to cover all possible scenarios that I could think of

            /*
             * There are a number of different conditionns that need to be considered
             * - The player needs to have an account and be logged in to start a game
             * - If the above conditions are not met, he will simply get an error message explainig why
             * - This may be the first play that starts the game, if so the level will be constructed, he will be sent a packet for info on his playe
             * - If there are already clients online, then they need to know about this new player who has joined, and he needs to know about himself and them
             * - Next... need to consider the fact that the other clients on the server are in game or not, if they are not in a game, and in the lobby then they
             *   do NOT need to know about this new player until they have started their own game
             * - If all players reach the exit, then the game simulation is cleared from memory
             * - Up to 4 players can join the same game at any time, and the game session is considered over when all players have either reached the goal or quit out
             * - In an edge case situation.... two players start a game >> player 1 finished level and goes back to lobby >> player 2 is still playing >> player 1 can re-enter
             *   using the same internal game object, the player count will still  be incremented as this could go on forever otherwise
             */

            int clientId = -1;

            // Extract the id of the sender
            if (json.ContainsKey("id"))
            {
                clientId = (int)((long)json["id"]);
            }
            else
            {
                Logger.Log("Error Parsing client id in start game packet", Logger.LogPrio.Error);
            }

            // Check that this id is in our client hash table
            if (!m_ServerManager.ClientExists(clientId))
            {
                Logger.Log(string.Format("Error client id {0} does not exist", clientId), Logger.LogPrio.Error);
                return(false);
            }

            // Client must be logged in!!
            if (Server.ServerManager.instance.GetClient(clientId).loggedIn == false)
            {
                PacketDefs.msgPacket returnPack = new PacketDefs.msgPacket();
                returnPack.msg     = "Error: not logged in";
                returnPack.success = false;
                ServerManager.instance.SendTcp(ServerManager.instance.GetClient(clientId).tcpSocket, fastJSON.JSON.ToJSON(returnPack, PacketDefs.JsonParams()));
                return(false);
            }
            // Game must not be full !!
            else if (m_GameSimulation.GetPlayersInGame() >= 4)
            {
                PacketDefs.msgPacket returnPack = new PacketDefs.msgPacket();
                returnPack.msg     = "Game is full please wait";
                returnPack.success = false;
                ServerManager.instance.SendTcp(ServerManager.instance.GetClient(clientId).tcpSocket, fastJSON.JSON.ToJSON(returnPack, PacketDefs.JsonParams()));
                return(false);
            }
            else
            {
                // This is first client so load level data
                if (!m_GameSimulation.IsGameDataLoaded())
                {
                    m_GameSimulation.LoadLevel(0);
                }

                GameClient thisClient = ServerManager.instance.GetClient(clientId);

                // Check if he is re-entering the same game
                if (thisClient.playerObjectHandle > -1)
                {
                    // Do we have a match
                    foreach (GameObject go in GameSimulation.instance.GetPlayers())
                    {
                        if (go.UnqId() == thisClient.playerObjectHandle && go.Active == false)
                        {
                            // The players already on will get an update to activate this in next tick
                            go.Active = true;

                            // Increment counter
                            GameSimulation.instance.AddNewPlayerToSession();
                        }
                    }
                }
                // Weird edge case: Previous client quit, but we still have a re-useable game object in memory so give him that
                else if (GameSimulation.instance.GetPlayers().Count == ServerManager.instance.NumClients())
                {
                    foreach (GameObject go in GameSimulation.instance.GetPlayers())
                    {
                        if (go.Active == false)
                        {
                            // The players already on will get an update to activate this in next tick
                            go.Active = true;

                            // Increment counter
                            GameSimulation.instance.AddNewPlayerToSession();

                            // Set the internal memoory handle store in client data
                            m_ServerManager.SetPlayerHandle(clientId, go.UnqId());

                            go.IsClient = 1;
                        }
                    }
                }
                else
                {
                    // This client is new to this game

                    // Set the internal memoory handle store in client data
                    m_ServerManager.SetPlayerHandle(clientId, m_GameSimulation.NumObjects());

                    // Add new client to game sim

                    GameObject newPlayer = new Player(Player.SpawnPosition(), GameObjectType.Player, m_GameSimulation.NumObjects(), 1, true, clientId,
                                                      new Vector2(96, 96), new ColliderOffset(26, 26, 30, 0));
                    //new Vector2(128, 128), new ColliderOffset(46,46,50,0));
                    m_GameSimulation.AddGameObject(newPlayer);

                    // Create Packet of one game object (this player) to send to other clients already on server with just this player. *note* last param (isClient) is set to 0 intentionally
                    PacketDefs.MultiGameObjectPacket thisClientPacket = new PacketDefs.MultiGameObjectPacket(1);
                    thisClientPacket.objects[0] = new PacketDefs.GameObjectPacket(
                        (int)newPlayer.TypeId(), newPlayer.UnqId(), newPlayer.Position.X, newPlayer.Position.Y, 0);

                    // This flag signifies if we actually need to  load the level,m because the other client is either in game or lobby then we don't want this
                    thisClientPacket.loadLevel = false;

                    // 1 - Send any clients on the server the new one that has been added
                    string data = fastJSON.JSON.ToJSON(thisClientPacket, PacketDefs.JsonParams());
                    foreach (KeyValuePair <int, GameClient> kvp in ServerManager.instance.GetClients())
                    {
                        // - Make sure it is not this client: He is included in the all clients packet and doesnt need to know
                        // - Make sure they are logged : Because they need to be
                        // - Make sure they are in game: Because they will get duplicates when they call this function otherwise

                        // This basically allows controls over the different stages, handles whether we are logged in or not and allows
                        // to drop in the game at any time
                        if (kvp.Key != clientId && kvp.Value.loggedIn && kvp.Value.inGame)
                        {
                            ServerManager.instance.SendTcp(kvp.Value.tcpSocket, data);
                        }
                    }
                }

                // Create Packet for list of all clients now to send to new player including himself
                PacketDefs.MultiGameObjectPacket allClientsPacket =
                    new PacketDefs.MultiGameObjectPacket(m_ServerManager.NumClients());
                allClientsPacket.loadLevel = true;

                // Fill it with data
                int i = 0;
                foreach (GameObject p in m_GameSimulation.GetObjects())
                {
                    if (p.TypeId() == GameObjectType.Player)
                    {
                        allClientsPacket.objects[i] = new PacketDefs.GameObjectPacket(
                            (int)p.TypeId(),
                            p.UnqId(),
                            p.Position.X,
                            p.Position.Y,
                            p.IsClient
                            );

                        ++i;
                    }
                }

                // Prevents duplicates
                thisClient.inGame = true;

                // 2 - Send the new client his own player details and the other players in the game
                m_ServerManager.SendTcp(thisClient.tcpSocket, fastJSON.JSON.ToJSON(allClientsPacket, PacketDefs.JsonParams()));

                // Set all players 'isClient' flag to null now that packets are sent
                foreach (GameObject player in GameSimulation.instance.GetPlayers())
                {
                    player.IsClient = 0;
                }

                return(true);
            }
        }
Example #9
0
        private bool UserLoginMsg(Dictionary <string, object> json)
        {
            Logger.Log("Got Login message");

            // Data to extract form this packet
            string name     = "";
            string password = "";
            int    clientId = -1;

            // Extract the id of the sender
            if (json.ContainsKey("id"))
            {
                clientId = (int)((long)json["id"]);
            }
            else
            {
                Logger.Log("Error Parsing client id in start game packet", Logger.LogPrio.Error);
                return(false);
            }

            if (json.ContainsKey("userName"))
            {
                name = (string)json["userName"];
            }

            if (json.ContainsKey("password"))
            {
                password = (string)json["password"];
            }

            // Send Packet with the return value of AddnewUserToDatabase as the argument for success
            PacketDefs.msgPacket returnPack = new PacketDefs.msgPacket();

            // Check this first as it's quicker than hitting database
            if (!ServerManager.instance.ClientExists(clientId))
            {
                string err = string.Format("Tried to create account with unknown client id: {0}", clientId);
                Logger.Log(err, Logger.LogPrio.Error);
                returnPack.success = false;
                returnPack.msg     = err;
            }
            else if (ServerManager.instance.GetClient(clientId).loggedIn)
            {
                returnPack.success = false;
                returnPack.msg     = "You are already logged in";
            }
            else
            {
                returnPack.msg = ServerManager.instance.Login(name, password, clientId, out returnPack.success);
            }

            // Send the info as udp
            ServerManager.instance.SendUdp(clientId, fastJSON.JSON.ToJSON(returnPack, PacketDefs.JsonParams()));

            // Send them an exp update
            GameClient thisClient = ServerManager.instance.GetClient(clientId);

            if (thisClient != null)
            {
                int expFromDB = ServerManager.instance.GetClientExp(name);
                thisClient.localExpCache = expFromDB;

                PacketDefs.UpdateExpPacket flp = new PacketDefs.UpdateExpPacket(expFromDB, PacketDefs.ID.OUT_TCP_ExpQueery);
                ServerManager.instance.SendTcp(ServerManager.instance.GetClient(clientId).tcpSocket, fastJSON.JSON.ToJSON(flp, PacketDefs.JsonParams()));
                return(true);
            }
            else
            {
                return(false);
            }
        }