public void HandleAcknowledgePacket(AcknowledgePacket packet) { if (packet is Ack) { foreach (int p in packet.Packets) { DataPacket pk; this.SendedPacket.TryRemove(p, out pk); } } else if (packet is Nack) { foreach (int p in packet.Packets) { if (this.SendedPacket.ContainsKey(p)) { DataPacket pk = this.SendedPacket[p]; DataPacket remove; this.ResendQueue.Enqueue(pk); this.SendedPacket.TryRemove(p, out remove); } } } }
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; } } }
/// <summary> /// All incoming packets are handled through this and then directed to the appropriate function /// </summary> /// <param name="receivedPacket"></param> public void ProcessPacket(BasePacket receivedPacket) { if (connect == null) { } if (receivedPacket == null) { Debug.Log("tis null"); } if (!isAuthenticated && receivedPacket.isAuthenticated()) { isAuthenticated = true; } List <SubPacket> subPackets = receivedPacket.GetSubpackets(); foreach (SubPacket subPacket in subPackets) { /* var stdOut = System.Console.Out; * var consoleOut = new System.IO.StringWriter(); * System.Console.SetOut(consoleOut); * subPacket.debugPrintSubPacket(); * Debug.Log(consoleOut.ToString()); * System.Console.SetOut(stdOut);*/ DoAuthenticationChecks(receivedPacket, subPacket); if (!receivedPacket.isAuthenticated()) { if (subPacket.header.type == (ushort)SubPacketTypes.ErrorPacket) { if (subPacket.gameMessage.opcode == (ushort)GamePacketOpCode.AccountError) { ErrorPacket ep = new ErrorPacket(); ep.ReadPacket(subPacket.data); string msg = ep.GetErrorMessage(); StatusBoxHandler.statusText = msg; Debug.Log("fam error packet"); Utils.SetAccountName(null); StatusBoxHandler.readyToClose = true; } } if (subPacket.gameMessage.opcode == (ushort)GamePacketOpCode.RegisterSuccess) { StatusBoxHandler.statusText = Encoding.Unicode.GetString(subPacket.data); StatusBoxHandler.readyToClose = true; break; } } else { if (subPacket.header.type == (ushort)SubPacketTypes.ErrorPacket) { switch (subPacket.gameMessage.opcode) { case ((ushort)GamePacketOpCode.CreateCharacterError): { StatusBoxHandler.statusText = "Character name has already been taken"; StatusBoxHandler.readyToClose = true; break; } } } switch (subPacket.gameMessage.opcode) { //TODO: Refactor statusbox ready to close to use event system case ((ushort)GamePacketOpCode.AccountSuccess): StatusBoxHandler.statusText = Encoding.Unicode.GetString(subPacket.data); isAuthenticated = true; loggedInSuccessfully = true; StatusBoxHandler.readyToClose = true; break; //TODO: Refactor statusbox ready to close to use event system case ((ushort)GamePacketOpCode.CreateCharacter): StatusBoxHandler.statusText = Encoding.Unicode.GetString(subPacket.data); StatusBoxHandler.readyToClose = true; break; //TODO: Refactor statusbox ready to close to use event system case ((ushort)GamePacketOpCode.CreateCharacterSuccess): StatusBoxHandler.statusText = Encoding.Unicode.GetString(subPacket.data); StatusBoxHandler.readyToClose = true; break; //TODO: Refactor this to use event system case ((ushort)GamePacketOpCode.CharacterListQuery): if (BitConverter.ToInt32(subPacket.data, 0) == -1) { CharacterLoader.serverResponseFinished = true; break; } else { characterLoader.SetCharacterListFromServer(subPacket); //else send each received packet to CharacterLoader to process } break; case ((ushort)GamePacketOpCode.CharacterDeleteSuccess): StatusBoxHandler.statusText = Encoding.Unicode.GetString(subPacket.data); StatusBoxHandler.readyToClose = true; break; case ((ushort)GamePacketOpCode.Acknowledgement): Debug.Log("Gets here"); AcknowledgePacket ack = new AcknowledgePacket(subPacket.data); GameEventManager.TriggerHandshakeResponseReceived(new GameEventArgs { serverResponse = ack.AckSuccessful }); //ackpacket has other data which is useful which i'm currently unsure on how to use atm //anything set here won't be visible when scene is changed to world map. break; default: Debug.Log("Unknown or corrupted packet"); break; } } } }
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; } } }