private void HandleNearbyActorsQuery(SubPacket subPacket)
        {
            PositionsInBoundsPacket posInBoundsPacket = new PositionsInBoundsPacket(subPacket.data);

            client.Character.SetCharacterCameraBounds(posInBoundsPacket.XMin, posInBoundsPacket.XMax, posInBoundsPacket.YMin, posInBoundsPacket.YMax);
            bool             foundNearby      = false;
            List <SubPacket> nearbyCharacters = new List <SubPacket>();
            var connectedPlayers = WorldServer.mConnectedPlayerList.Values.ToList();

            foreach (var connectedPlayer in connectedPlayers)
            {
                if ((connectedPlayer.CharacterId != client.Character.CharacterId) && connectedPlayer.XPos > client.Character.BoundsXMin &&
                    connectedPlayer.XPos < client.Character.BoundsXMax && connectedPlayer.YPos > client.Character.BoundsYMin &&
                    connectedPlayer.YPos < client.Character.BoundsYMax)
                {
                    foundNearby = true;
                    PositionPacket packet = new PositionPacket(connectedPlayer.XPos, connectedPlayer.YPos, true, connectedPlayer.CharacterId);
                    SubPacket      sp     = new SubPacket(GamePacketOpCode.NearbyActorsQuery, 0, connectedPlayer.CharacterId, packet.GetBytes(), SubPacketTypes.GamePacket);
                    nearbyCharacters.Add(sp);
                }
            }
            if (foundNearby)
            {
                client.QueuePacket(BasePacket.CreatePacket(nearbyCharacters, true, false));
                client.FlushQueuedSendPackets();
            }
        }
        /// <summary>
        /// contact login server and ensure that the ipaddress of player is currently connected to it
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="subPacket"></param>
        private void ConfirmClientConnectionWithLoginServer(Socket socket, SubPacket subPacket)
        {
            Console.WriteLine("Confirming client connection with login server");
            IPAddress[] ip        = Dns.GetHostAddresses(LOGIN_SERVER_IP);
            Character   character = new Character(BitConverter.ToUInt32(subPacket.data, 0));

            client.HasHandshakedWorldServerToClient = true;
            character.WorldClientConnection         = client;

            if (!WorldServer.mConnectedPlayerList.ContainsKey(character.CharacterId))
            {
                Console.WriteLine("Inserting character into dictionary:  " + character.CharacterId);
                WorldServer.mConnectedPlayerList.TryAdd(character.CharacterId, character);
            }
            else
            {
                Console.WriteLine("WARNING! : Connected player already exists and trying to add them into list");
            }

            IPEndPoint remoteEP = new IPEndPoint(ip[0], LOGIN_SERVER_PORT);

            socket.Connect(remoteEP);
            HandshakePacket packet = new HandshakePacket(client.GetIp(), client.GetPort(), character.CharacterId);

            Console.WriteLine("PORT FROM CLIENT:" + client.GetPort());
            Console.WriteLine("IP FROM CLIENT:" + client.GetIp());
            Console.WriteLine("CHARACTER ID FROM CLIENT: " + character.CharacterId);
            SubPacket  sp           = new SubPacket(GamePacketOpCode.Handshake, 0, 0, packet.GetBytes(), SubPacketTypes.GamePacket);
            BasePacket packetToSend = BasePacket.CreatePacket(sp, true, false);

            //send packet to login server for confirmation
            WorldClientConnection connectionToLoginServer = new WorldClientConnection();

            connectionToLoginServer.socket = socket;
            connectionToLoginServer.QueuePacket(packetToSend);
            connectionToLoginServer.FlushQueuedSendPackets();
            connectionToLoginServer.Disconnect();
        }
        private void ProcessGenericPackets(List <SubPacket> subPackets)
        {
            foreach (SubPacket subPacket in subPackets)
            {
                subPacket.debugPrintSubPacket();
                Console.WriteLine(subPacket.gameMessage.opcode);
                switch (subPacket.gameMessage.opcode)
                {
                //contact login server and ensure that ipaddress of player is currently connected to

                case ((ushort)GamePacketOpCode.Handshake):
                    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    try
                    {
                        IPAddress[] ip          = Dns.GetHostAddresses(LOGIN_SERVER_IP);
                        int         characterId = BitConverter.ToInt32(subPacket.data, 0);
                        client.CharacterId         = characterId;
                        client.WorldServerToClient = true;
                        IPEndPoint remoteEP = new IPEndPoint(ip[0], LOGIN_SERVER_PORT);
                        socket.Connect(remoteEP);
                        HandshakePacket packet = new HandshakePacket(client.GetIp(), client.GetPort(), characterId);
                        //Console.WriteLine("PORT FROM CLIENT:" + client.GetPort());
                        //Console.WriteLine("IP FROM CLIENT:" + client.GetIp());
                        //Console.WriteLine("CHARACTER ID FROM CLIENT: " + client.CharacterId);
                        SubPacket             sp           = new SubPacket(GamePacketOpCode.Handshake, 0, 0, packet.GetBytes(), SubPacketTypes.GamePacket);
                        BasePacket            packetToSend = BasePacket.CreatePacket(sp, true, false);
                        WorldClientConnection loginServer  = new WorldClientConnection();
                        loginServer.socket = socket;
                        loginServer.QueuePacket(packetToSend);
                        loginServer.FlushQueuedSendPackets();
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                    }
                    break;


                case (((ushort)GamePacketOpCode.Acknowledgement)):

                    AcknowledgePacket ack = new AcknowledgePacket(subPacket.data);
                    if (ack.AckSuccessful)
                    {
                        foreach (var mClient in WorldServer.GetClientConnections())     //check this if any performance issues
                        {
                            Console.WriteLine(ack.CharacterId);
                            if (mClient.CharacterId == ack.CharacterId && mClient.WorldServerToClient) //this is getting the wrong client
                            {                                                                          //maybe set a boolean in clientconnection that tells whether or not client is created from a server to server communication
                                ConnectedPlayer connectedPlayer = new ConnectedPlayer(ack.CharacterId);
                                connectedPlayer.ClientAddress = ack.ClientAddress;
                                WorldServer.mConnectedPlayerList.Add(connectedPlayer.actorId, connectedPlayer);
                                client = mClient;
                                SubPacket sp = new SubPacket(GamePacketOpCode.Acknowledgement, 0, 0, subPacket.data, SubPacketTypes.GamePacket);
                                client.QueuePacket(BasePacket.CreatePacket(sp, true, false));
                                client.FlushQueuedSendPackets();
                                Console.WriteLine("Sending ack back to: " + client.GetFullAddress());
                                break;
                            }
                        }
                    }

                    break;



                //if everything okay


                default:
                    break;
                }
            }
        }
Beispiel #4
0
/*
 *      public static Actor GetStaticActors(uint id)
 *      {
 *          return mStaticActors.GetActor(id);
 *      }
 *
 *      public static Actor GetStaticActors(string name)
 *      {
 *          return mStaticActors.FindStaticActor(name);
 *      }
 *
 *      public static Item GetItemGamedata(uint id)
 *      {
 *          if (gamedataItems.ContainsKey(id))
 *              return gamedataItems[id];
 *          else
 *              return null;
 *      }*/

        /// <summary>
        /// Receive Callback. Reads in incoming data, converting them to base packets. Base packets are sent to be parsed. If not enough data at the end to build a basepacket, move to the beginning and prepend.
        /// </summary>
        /// <param name="result"></param>
        private void ReceiveCallback(IAsyncResult result)
        {
            WorldClientConnection conn = (WorldClientConnection)result.AsyncState;

            //Check if disconnected
            if ((conn.socket.Poll(1, SelectMode.SelectRead) && conn.socket.Available == 0))
            {
                lock (mConnectionList)
                {
                    mConnectionList.Remove(conn);
                }
                if (conn.connType == BasePacket.TYPE_ZONE)
                {
                    Console.WriteLine("{0} has disconnected.", conn.owner == 0 ? conn.GetFullAddress() : "User " + conn.owner);
                }
                return;
            }

            try
            {
                int bytesRead = conn.socket.EndReceive(result);

                bytesRead += conn.lastPartialSize;

                if (bytesRead >= 0)
                {
                    int offset = 0;

                    //Build packets until can no longer or out of data
                    while (true)
                    {
                        BasePacket basePacket = BuildPacket(ref offset, conn.buffer, bytesRead);

                        //If can't build packet, break, else process another
                        if (basePacket == null)
                        {
                            break;
                        }
                        else
                        {
                            mProcessor.ProcessPacket(conn, basePacket);
                        }
                    }

                    //Not all bytes consumed, transfer leftover to beginning
                    if (offset < bytesRead)
                    {
                        Array.Copy(conn.buffer, offset, conn.buffer, 0, bytesRead - offset);
                    }

                    conn.lastPartialSize = bytesRead - offset;

                    //Build any queued subpackets into basepackets and send
                    conn.FlushQueuedSendPackets();

                    if (offset < bytesRead)
                    {
                        //Need offset since not all bytes consumed
                        conn.socket.BeginReceive(conn.buffer, bytesRead - offset, conn.buffer.Length - (bytesRead - offset), SocketFlags.None, new AsyncCallback(ReceiveCallback), conn);
                    }
                    else
                    {
                        //All bytes consumed, full buffer available
                        conn.socket.BeginReceive(conn.buffer, 0, conn.buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), conn);
                    }
                }
                else
                {
                    Console.WriteLine("{0} has disconnected.", conn.owner == 0 ? conn.GetFullAddress() : "User " + conn.owner);

                    lock (mConnectionList)
                    {
                        mConnectionList.Remove(conn);
                    }
                }
            }
            catch (SocketException)
            {
                if (conn.socket != null)
                {
                    Console.WriteLine("{0} has disconnected.", conn.owner == 0 ? conn.GetFullAddress() : "User " + conn.owner);

                    lock (mConnectionList)
                    {
                        mConnectionList.Remove(conn);
                    }
                }
            }
        }
        private void ProcessConnectPackets(List <SubPacket> subPackets)
        {
            foreach (SubPacket subPacket in subPackets)
            {
                subPacket.debugPrintSubPacket();
                switch (subPacket.gameMessage.opcode)
                {
                case ((ushort)GamePacketOpCode.Handshake):
                    try
                    {
                        Console.WriteLine("100% CORRECT CLIENT CONNECTION: " + client.GetFullAddress());
                        ConfirmClientConnectionWithLoginServer(new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp), subPacket);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                    }
                    break;


                case (((ushort)GamePacketOpCode.Acknowledgement)):

                    AcknowledgePacket ack = new AcknowledgePacket(subPacket.data);
                    if (ack.AckSuccessful)
                    {
                        if (WorldServer.mConnectedPlayerList.TryGetValue(ack.CharacterId, out Character character))
                        {
                            client.Disconnect();     //this is 100% login server connection, don't doubt this
                            client           = character.WorldClientConnection;
                            client.Character = character;
                            CharacterPositionsWrapper posDbWrapper = WorldDatabase.GetCharacterPosition(client.Character.CharacterId);
                            client.Character.XPos = posDbWrapper.XPos;
                            client.Character.YPos = posDbWrapper.YPos;
                            client.Character.Zone = posDbWrapper.Zone;
                            Console.WriteLine("Client looks legit: " + (ack.ClientAddress == client.GetIp()));

                            WorldDatabase.AddToOnlinePlayerList(character.CharacterId, ack.ClientAddress);
                            client.SessionId = WorldDatabase.GetSessionId(character.CharacterId);
                            Console.WriteLine("Sending ack received from login server back to: " + client.GetFullAddress());
                            AcknowledgePacket responseAck = new AcknowledgePacket(ack.AckSuccessful, client.SessionId);
                            SubPacket         sp          = new SubPacket(GamePacketOpCode.Acknowledgement, 0, 0, responseAck.GetResponseFromWorldServerBytes(), SubPacketTypes.GamePacket);
                            client.QueuePacket(BasePacket.CreatePacket(sp, true, false));
                            client.FlushQueuedSendPackets();
                            break;
                        }
                        else
                        {
                            Console.WriteLine("Client has connected but is not in Connected Player List.. Not sure what to do here");
                        }
                    }
                    else
                    {
                        Console.WriteLine("Ack not successful, removing from connected player list");
                        WorldServer.mConnectedPlayerList.TryRemove(ack.CharacterId, out Character unsuccessfulAckCharacter);
                        client.Disconnect();
                    }
                    break;

                case (((ushort)GamePacketOpCode.Disconnect)):
                    DisconnectPacket dc = new DisconnectPacket(subPacket.data);
                    Console.WriteLine("Got DC packet");
                    WorldDatabase.RemoveFromOnlinePlayerList(dc.CharacterId);
                    WorldServer.mConnectedPlayerList.TryRemove(dc.CharacterId, out Character characterToDc);
                    client.Disconnect();
                    break;

                //if everything okay
                default:
                    break;
                }
            }
        }