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; } } }
/* * 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; } } }