private void ProcessCharacterListQueryPacket(SubPacket receivedPacket) { Database db = new Database(); CharacterQueryPacket cq = new CharacterQueryPacket(); string accountName = cq.ReadAccountName(receivedPacket); Console.WriteLine("account name for CL: " + accountName); var accountId = db.GetAccountIdFromAccountName(accountName); Console.WriteLine("ID for CL: " + accountId); var characterList = db.GetListOfCharacters(accountId); var packets = cq.BuildResponsePacket(characterList); Console.WriteLine("Character packeted authenticated = " + client.authenticated); BasePacket packetsToSend = BasePacket.CreatePacket(packets, client.authenticated, false); Console.WriteLine("---Character Query Packet---"); for (var i = 0; i < characterList.Count; i++) { int characterId = int.Parse(characterList[i][0]); client.CharacterIds[i] = characterId; } packetsToSend.debugPrintPacket(); client.QueuePacket(packetsToSend); }
public static BasePacket CreatePacket(SubPacket subpacket, bool isAuthed, bool isEncrypted) { //Create Header BasePacketHeader header = new BasePacketHeader(); byte[] data = null; header.isAuthenticated = isAuthed ? (byte)1 : (byte)0; header.isEncrypted = isEncrypted ? (byte)1 : (byte)0; header.numSubpackets = 1; header.packetSize = BASEPACKET_SIZE; header.timestamp = Utils.MilisUnixTimeStampUTC(); //Get packet size header.packetSize += subpacket.header.subpacketSize; data = new byte[header.packetSize - 0x10]; //Add Subpackets byte[] subpacketData = subpacket.getBytes(); Array.Copy(subpacketData, 0, data, 0, subpacketData.Length); Debug.Assert(data != null); BasePacket packet = new BasePacket(header, data); return(packet); }
private void PerformCharacterCreate(SubPacket subPacket) { LoginDatabase db = new LoginDatabase(); CharacterCreatePacket cp = new CharacterCreatePacket(subPacket.data); try { db.AddCharacterToDb(ap.userName, cp); SubPacket success = new SubPacket(GamePacketOpCode.CreateCharacterSuccess, 0, 0, System.Text.Encoding.Unicode.GetBytes("Character created successfully"), SubPacketTypes.GamePacket); BasePacket basePacket = BasePacket.CreatePacket(success, client.authenticated, false); client.QueuePacket(basePacket); } catch (MySqlException e) { ErrorPacket ep = new ErrorPacket(); SubPacket packetToSend; if (e.Number == (int)ErrorCodes.DuplicateCharacter) { packetToSend = ep.buildPacket(GamePacketOpCode.CreateCharacterError, ErrorCodes.DuplicateCharacter, "Character with that name already exists"); } else { packetToSend = ep.buildPacket(GamePacketOpCode.CreateCharacterError, ErrorCodes.UnknownDatabaseError, "Unknown database error occurred"); } QueueErrorPacket(packetToSend); } }
//client in this case will be WorldServer private void ProcessHandshake(SubPacket receivedPacket) { //search connected clients for address //send characterid and address from receivedPacket back to worldserver HandshakePacket received = new HandshakePacket(receivedPacket.data); foreach (var connection in LoginServer.mConnectionList) { //Console.WriteLine("id present: "+characterIdPresentInClient(received.CharacterId, connection)); //Console.WriteLine("client id: " + received.CharacterId); //Console.WriteLine("connection id: " + connection.CharacterId[0]); if (connection.GetIp() == received.ClientAddress && characterIdPresentInClient(received.CharacterId, connection)) { //TODO: Separate this into a method AcknowledgePacket ack = new AcknowledgePacket(true, received.ClientAddress, received.CharacterId); SubPacket sp = new SubPacket(GamePacketOpCode.Acknowledgement, 0, 0, ack.GetBytes(), SubPacketTypes.GamePacket); BasePacket successPacketToSend = BasePacket.CreatePacket(sp, true, false); AckResponseToWorldServer(successPacketToSend); return; } } AcknowledgePacket ackFailure = new AcknowledgePacket(true, received.ClientAddress, received.CharacterId); SubPacket fail = new SubPacket(GamePacketOpCode.Acknowledgement, 0, 0, ackFailure.GetBytes(), SubPacketTypes.GamePacket); BasePacket failPacketToSend = BasePacket.CreatePacket(fail, true, false); AckResponseToWorldServer(failPacketToSend); }
/// <summary> /// Builds a packet from the incoming buffer + offset. If a packet can be built, it is returned else null. /// </summary> /// <param name="offset">Current offset in buffer.</param> /// <param name="buffer">Incoming buffer.</param> /// <returns>Returns either a BasePacket or null if not enough data.</returns> public BasePacket BuildPacket(ref int offset, byte[] buffer, int bytesRead) { BasePacket newPacket = null; //Too small to even get length if (bytesRead <= offset) { return(null); } ushort packetSize = BitConverter.ToUInt16(buffer, offset); //Too small to whole packet if (bytesRead < offset + packetSize) { return(null); } if (buffer.Length < offset + packetSize) { return(null); } try { newPacket = new BasePacket(buffer, ref offset); } catch (OverflowException e) { Console.WriteLine(e.ToString()); return(null); } return(newPacket); }
public static unsafe void DecryptPacket(Blowfish blowfish, ref BasePacket packet) { byte[] data = packet.data; int size = packet.header.packetSize; int offset = 0; while (offset < data.Length) { if (data.Length < offset + SubPacket.SUBPACKET_SIZE) { throw new OverflowException("Packet Error: Subpacket was too small"); } SubPacketHeader header; fixed(byte *pdata = &data[offset]) { header = (SubPacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader)); } if (data.Length < offset + header.subpacketSize) { throw new OverflowException("Packet Error: Subpacket size didn't equal subpacket data"); } blowfish.Decipher(data, offset + 0x10, header.subpacketSize - 0x10); offset += header.subpacketSize; } }
private void PerformCharacterCreate(SubPacket subPacket) { Database db = new Database(); CharacterCreatePacket cp = new CharacterCreatePacket(subPacket.data); int error = db.AddCharacterToDb(ap.userName, cp); if (error == -1) { SubPacket success = new SubPacket(GamePacketOpCode.CreateCharacterSuccess, 0, 0, System.Text.Encoding.Unicode.GetBytes("Character created successfully"), SubPacketTypes.GamePacket); BasePacket basePacket = BasePacket.CreatePacket(success, client.authenticated, false); client.QueuePacket(basePacket); //created successfully } else { ErrorPacket ep = new ErrorPacket(); if (error == (int)ErrorCodes.DuplicateCharacter) { var packetToSend = ep.buildPacket(GamePacketOpCode.CreateCharacterError, ErrorCodes.DuplicateCharacter, "Character with that name already exists"); } if (error == (int)ErrorCodes.UnknownDatabaseError) { var packetToSend = ep.buildPacket(GamePacketOpCode.CreateCharacterError, ErrorCodes.UnknownDatabaseError, "Unknown database error occurred"); QueueErrorPacket(packetToSend); } } }
private void ProcessAccountPacket(ClientConnection client, SubPacket packet) { ap = new AccountPacket(); ErrorPacket ep = new ErrorPacket(); ap.Read(packet.GetAccountHeaderBytes(), packet.data); if (!ap.register)//if account is logging in { Database db = new Database(); List <string> account = db.CheckUserInDb(ap.userName, ap.password); switch (account.Count) { case 0: var packetToSend = ep.buildPacket(GamePacketOpCode.AccountError, ErrorCodes.NoAccount, "Account does not exist"); Console.WriteLine("Attempted log in for username: {0} pw: {1}, account does not exist", ap.userName, ap.password); QueueErrorPacket(packetToSend); break; case 1: //password incorrect packetToSend = ep.buildPacket(GamePacketOpCode.AccountError, ErrorCodes.WrongPassword, "Wrong username or password"); Console.WriteLine("Attempted log in for username: {0} pw: {1}, password incorrect", ap.userName, ap.password); QueueErrorPacket(packetToSend); break; case 2: //user and password found Console.WriteLine("Username: {0} Password: {1} has logged in successfully", account[0], account[1]); SubPacket success = new SubPacket(GamePacketOpCode.AccountSuccess, 0, 0, System.Text.Encoding.Unicode.GetBytes("Login Successful"), SubPacketTypes.GamePacket); client.authenticated = true; BasePacket basePacket = BasePacket.CreatePacket(success, client.authenticated, false); client.QueuePacket(basePacket); break; default: throw new Exception("somehow found more than 2 colums in DB"); } } else //account is registering { Database db = new Database(); var succeeded = db.AddUserToDb(ap.userName, ap.password); if (succeeded) { Console.WriteLine("Username: {0} Password: {1} has been registered successfully", ap.userName, ap.password); SubPacket success = new SubPacket(GamePacketOpCode.RegisterSuccess, 0, 0, System.Text.Encoding.Unicode.GetBytes("Registration Successful"), SubPacketTypes.GamePacket); BasePacket basePacket = BasePacket.CreatePacket(success, false, false); client.QueuePacket(basePacket); } else { var packetToSend = ep.buildPacket(GamePacketOpCode.AccountError, ErrorCodes.DuplicateAccount, "Account already registered"); QueueErrorPacket(packetToSend); } } }
private void AckResponseToWorldServer(BasePacket packetToSend) { packetToSend.header.connectionType = (ushort)BasePacketConnectionTypes.Generic; IPAddress[] ip = Dns.GetHostAddresses("127.0.0.1"); IPEndPoint remoteEP = new IPEndPoint(ip[0], 3435); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect(remoteEP); ClientConnection temp = new ClientConnection(); temp.socket = socket; temp.QueuePacket(packetToSend); temp.FlushQueuedSendPackets(); }
/// <summary> /// Builds a packet from the incoming buffer + offset. If a packet can be built, it is returned else null. /// </summary> /// <param name="offset">Current offset in buffer.</param> /// <param name="buffer">Incoming buffer.</param> /// <returns>Returns either a BasePacket or null if not enough data.</returns> public static BasePacket CreatePacket(ref int offset, byte[] buffer, int bytesRead) { BasePacket newPacket = null; //Too small to even get length if (bytesRead <= offset) { return(null); } ushort packetSize = BitConverter.ToUInt16(buffer, offset); //Too small to whole packet if (bytesRead < offset + packetSize) return(null); }
private void ProcessCharacterDeleteRequest(SubPacket receivedPacket) { Database db = new Database(); CharacterDeletePacket deletePacket = new CharacterDeletePacket(receivedPacket); int error = db.DeleteCharacterFromDb(deletePacket.CharId); if (error == -1) { SubPacket success = new SubPacket(GamePacketOpCode.CharacterDeleteSuccess, 0, 0, System.Text.Encoding.Unicode.GetBytes("Character deleted successfully"), SubPacketTypes.GamePacket); BasePacket basePacket = BasePacket.CreatePacket(success, client.authenticated, false); client.QueuePacket(basePacket); } else { //send error packet here } }
public void ProcessPacket(ClientConnection client, BasePacket packet) { this.client = client; // BasePacket.DecryptPacket(client.blowfish, ref packet); //else packet.debugPrintPacket(); List <SubPacket> subPackets = packet.GetSubpackets(); foreach (SubPacket subPacket in subPackets) { subPacket.debugPrintSubPacket(); if (subPacket.header.type == (ushort)SubPacketTypes.Account) { ProcessAccountPacket(client, subPacket); } if (subPacket.header.type == (ushort)SubPacketTypes.GamePacket) { switch (subPacket.gameMessage.opcode) { case (ushort)GamePacketOpCode.CreateCharacter: if (CheckCharacterCreatePacket(subPacket)) { PerformCharacterCreate(subPacket); } break; case (ushort)GamePacketOpCode.CharacterListQuery: ProcessCharacterListQueryPacket(subPacket); break; case (ushort)GamePacketOpCode.CharacterDeleteQuery: ProcessCharacterDeleteRequest(subPacket); break; case (ushort)GamePacketOpCode.Handshake: ProcessHandshake(subPacket); break; } } } }
public static BasePacket CreatePacket(byte[] data, bool isAuthed, bool isEncrypted) { Debug.Assert(data != null); //Create Header BasePacketHeader header = new BasePacketHeader(); header.isAuthenticated = isAuthed ? (byte)1 : (byte)0; header.isEncrypted = isEncrypted ? (byte)1 : (byte)0; header.numSubpackets = 1; header.packetSize = BASEPACKET_SIZE; header.timestamp = Utils.MilisUnixTimeStampUTC(); //Get packet size header.packetSize += (ushort)data.Length; BasePacket packet = new BasePacket(header, data); return(packet); }
/// <summary> /// Default BasePacketConnectionType = zone /// </summary> /// <param name="subpackets"></param> /// <param name="isAuthed"></param> /// <param name="isEncrypted"></param> /// <returns></returns> public static BasePacket CreatePacket(List <SubPacket> subpackets, bool isAuthed, bool isEncrypted, BasePacketConnectionTypes connectionType = BasePacketConnectionTypes.Zone) { //Create Header BasePacketHeader header = new BasePacketHeader(); byte[] data = null; header.isAuthenticated = isAuthed ? (byte)1 : (byte)0; header.isEncrypted = isEncrypted ? (byte)1 : (byte)0; header.numSubpackets = (ushort)subpackets.Count; header.packetSize = BASEPACKET_SIZE; header.timestamp = Utils.MilisUnixTimeStampUTC(); header.connectionType = (ushort)connectionType; //Get packet size foreach (SubPacket subpacket in subpackets) { header.packetSize += subpacket.header.subpacketSize; } data = new byte[header.packetSize - 0x10]; //Add Subpackets int offset = 0; foreach (SubPacket subpacket in subpackets) { byte[] subpacketData = subpacket.getBytes(); Array.Copy(subpacketData, 0, data, offset, subpacketData.Length); offset += (ushort)subpacketData.Length; } Debug.Assert(data != null && offset == data.Length && header.packetSize == 0x10 + offset); BasePacket packet = new BasePacket(header, data); return(packet); }
public void FlushQueuedSendPackets() { if (!socket.Connected) { return; } while (sendPacketQueue.Count > 0) { BasePacket packet = sendPacketQueue.Take(); byte[] packetBytes = packet.GetPacketBytes(); byte[] buffer = new byte[0xffff]; Array.Copy(packetBytes, buffer, packetBytes.Length); try { socket.Send(packetBytes); } catch (Exception e) { Console.WriteLine(string.Format("Weird case, socket was d/ced: {0}", e)); } } }
public void QueuePacket(BasePacket packet) { sendPacketQueue.Add(packet); }
private void ReceiveCallBack(IAsyncResult ar) { //need to setup buffer of length PacketController // Retrieve the state object and the handler socket // from the asynchronous state object. ClientConnection client = (ClientConnection)ar.AsyncState; try { int bytesRead = client.socket.EndReceive(ar); Console.WriteLine("bytes read" + bytesRead); //allows to pause traffic and restart for debugging purposes. bytesRead += client.lastPartialSize; if (bytesRead > 0) { int offset = 0; //build/compile packets until can no longer or data is finished while (client.socket.Connected) { BasePacket basePacket = BuildPacket(ref offset, client.buffer, bytesRead); if (basePacket == null) { break; } else { client.PacketProcessor.ProcessPacket(client, basePacket); } } //Not all bytes consumed, transfer leftover to beginning if (offset < bytesRead) { Array.Copy(client.buffer, offset, client.buffer, 0, bytesRead - offset); } Array.Clear(client.buffer, bytesRead - offset, client.buffer.Length - (bytesRead - offset)); //allows to pause traffic and restart for debugging purposes. client.lastPartialSize = bytesRead - offset; //Build any queued subpackets into basepackets and send client.FlushQueuedSendPackets(); if (offset < bytesRead) //need offset since not all bytes consumed { client.socket.BeginReceive(client.buffer, bytesRead - offset, client.buffer.Length - (bytesRead - offset), SocketFlags.None, new AsyncCallback(ReceiveCallBack), client); } else { client.socket.BeginReceive(client.buffer, 0, client.buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), client); } } else { Console.WriteLine("Client at {0} has disconnected", client.GetFullAddress()); lock (mConnectionList) { client.Disconnect(); mConnectionList.Remove(client); } } } catch (SocketException) { if (client.socket != null) { client.socket.Disconnect(false); Console.WriteLine("Client at {0} has disconnected", client.GetFullAddress()); lock (mConnectionList) { mConnectionList.Remove(client); } } } }
private void QueueErrorPacket(SubPacket subPacket) { BasePacket errorBasePacket = BasePacket.CreatePacket(subPacket, client.authenticated, false); client.QueuePacket(errorBasePacket); }