private async Task HandleChallengeRequest() { var random = new Random(); var token = random.Next(); var builder = new PacketBuilder(); builder.AddInt16(0x0001); builder.AddByte(0x03); builder.AddByte(0x00); builder.AddInt32(token); var buffer = builder.GetBytes(); await this.networkClient.SendAsync(buffer, buffer.Length); var result = await this.networkClient.ReceiveAsync(); PacketReader reader = new PacketReader(result); reader.ReadInt16(); reader.ReadByte(); reader.ReadByte(); var responseToken = reader.ReadInt32(); if (responseToken != token) { throw new InvalidOperationException("Invalid token response from server."); } }
private void Login(string user, string pass) { //try to connect. if (!GameClient.NetClient.Connected) { GameClient.NetClient.Connect(); } //if failed, try 10 times, then error out if (!GameClient.NetClient.Connected) { DisplayMessage("Connection to game server could not be found!"); } else { //sending packet payload to the server PacketBuilder pb = new PacketBuilder(PacketFamily.LOGIN, PacketAction.REQUEST); pb = pb.AddByte((byte)_txtUser.Text.Length) .AddString(_txtUser.Text) .AddByte((byte)_txtPassword.Text.Length) .AddString(_txtPassword.Text); GameClient.NetClient.Send(pb.Build()); Console.WriteLine("Attempting to login using user: {0} pass: {1}", _txtUser.Text, _txtPassword.Text); } }
/// <summary> /// Adds instance bytes to packet builder. /// </summary> protected override void AddInstanceBytes(PacketBuilder builder) { builder.AddUInt16((ushort)_commandType); builder.AddInt32(_sequence); builder.AddByte((byte)_code); builder.AddBytes(_data); }
public void BuildWithoutCrcReturnPacket() { for (int index = 0; index < HeartbeatPacketBytes.Length - 2; index++) { byte packetByte = HeartbeatPacketBytes[index]; PacketBuilder.AddByte(packetByte); } // Checksum PacketBuilder.AddByte(0x00); PacketBuilder.AddByte(0x00); MessageId expectedMessageId = MessageId.Heartbeat; byte expectedPayloadLegth = 9; byte expectedSequenceNumber = 78; byte expectedSystemId = 1; byte expectedHeader = Packet.HeaderValue; byte[] expectedChecksum = { 0x1C, 0x7F }; byte[] expectedPayload = { 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x51, 0x04, 0x03 }; Packet packet = PacketBuilder.Build(BuildType.WithoutCrc); Assert.AreNotEqual(null, packet); Assert.AreEqual(expectedMessageId, packet.MessageId); Assert.AreEqual(expectedPayloadLegth, packet.PayloadLength); Assert.AreEqual(expectedSequenceNumber, packet.SequenceNumber); Assert.AreEqual(expectedSystemId, packet.SystemId); Assert.AreEqual(expectedHeader, packet.Header); Assert.AreEqual(expectedChecksum, packet.Checksum); Assert.AreEqual(expectedPayload, packet.Payload); }
private void BtnRegister_OnClick(object sender, ClickedEventArgs e) { //making sure that passwords match and the email has been successfully validated if (txtPassword.Text == txtRepeat.Text && eValidator.Validate(txtEmail.Text)) { if (!GameClient.NetClient.Connected) { GameClient.NetClient.Connect(); } if (!GameClient.NetClient.Connected) { DisplayMessage("Connection to game server could not be found!"); } else { //if we have connected to the game server and everything checks out, we're going to register to the server PacketBuilder pb = new PacketBuilder(PacketFamily.REGISTER, PacketAction.REQUEST); pb = pb.AddByte((byte)txtUsername.Text.Length) .AddString(txtUsername.Text) .AddByte((byte)txtPassword.Text.Length) .AddString(txtPassword.Text) .AddByte((byte)txtEmail.Text.Length) .AddString(txtEmail.Text) .AddByte((byte)txtFullname.Text.Length) .AddString(txtFullname.Text); GameClient.NetClient.Send(pb.Build()); } } }
public void BuildWithCrcReturnPacket() { foreach (byte packetByte in HeartbeatPacketBytes) { PacketBuilder.AddByte(packetByte); } MessageId expectedMessageId = MessageId.Heartbeat; byte expectedPayloadLegth = 9; byte expectedSequenceNumber = 78; byte expectedSystemId = 1; byte expectedHeader = Packet.HeaderValue; byte[] expectedChecksum = { 0x1C, 0x7F }; byte[] expectedPayload = { 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x51, 0x04, 0x03 }; Packet packet = PacketBuilder.Build(); Assert.AreNotEqual(null, packet); Assert.AreEqual(expectedMessageId, packet.MessageId); Assert.AreEqual(expectedPayloadLegth, packet.PayloadLength); Assert.AreEqual(expectedSequenceNumber, packet.SequenceNumber); Assert.AreEqual(expectedSystemId, packet.SystemId); Assert.AreEqual(expectedHeader, packet.Header); Assert.AreEqual(expectedChecksum, packet.Checksum); Assert.AreEqual(expectedPayload, packet.Payload); }
public void BuildWithCrcReturnNull() { PacketBuilder.AddByte(HeartbeatPacketBytes[0]); Packet packet = PacketBuilder.Build(); Assert.AreEqual(null, packet); }
/// <summary> /// Play button clicked handler /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnPlayChar_OnClick(object sender, CustomEventArgs.ClickedEventArgs e) { if (((Control)sender).IsVisible) { int id = Convert.ToInt32(((Control)sender).Name[((Control)sender).Name.Length - 1]) - 48; PacketBuilder pb = new PacketBuilder(PacketFamily.PLAY, PacketAction.REQUEST); pb = pb.AddByte((byte)id); GameClient.NetClient.Send(pb.Build()); } }
private void _btnCreateChar_OnClick(object sender, ClickedEventArgs e) { //character creation request PacketBuilder pb = new PacketBuilder(PacketFamily.CHARACTER, PacketAction.CREATE); pb = pb.AddByte((byte)_txtCharacterName.Text.Length) .AddString(_txtCharacterName.Text) .AddByte((byte)playerCharacter.Gender); GameClient.NetClient.Send(pb.Build()); Logger.Log("Character create requested"); }
public void AddByteReturnsTrue() { for (int i = 0; i < HeartbeatPacketBytes.Length - 1; i++) { bool completed = PacketBuilder.AddByte(HeartbeatPacketBytes[i]); } bool result = PacketBuilder.AddByte(HeartbeatPacketBytes[HeartbeatPacketBytes.Length - 1]); Assert.AreEqual(true, result); }
private async Task HandleClientRequest() { var builder = new PacketBuilder(); builder.AddInt16(0x0003); builder.AddBytes(new byte[6]); builder.AddByte(0x01); builder.AddString("Infantry", 9); builder.AddBytes(new byte[16]); var buffer = builder.GetBytes(); await this.networkClient.SendAsync(buffer, buffer.Length); }
private void btnDeleteChar_OnClick(object sender, CustomEventArgs.ClickedEventArgs e) { if (((Control)sender).IsVisible) { if (sender is Button) { Button deleteButton = (Button)sender; int id = Convert.ToInt32(deleteButton.Name[deleteButton.Name.Length - 1]) - 48; PacketBuilder pb = new PacketBuilder(PacketFamily.CHARACTER, PacketAction.DELETE); pb = pb.AddByte((byte)id); GameClient.NetClient.Send(pb.Build()); } } }
public byte[] ToBytes() { PacketBuilder builder = new PacketBuilder(); builder.AddInt32(PACKET_HEADER); builder.AddByte((byte)_type); builder.AddString(_gameTitle); builder.AddVersion(_gameVersion); builder.AddIPAddress(_sourceIP); builder.AddIPAddress(_destinationIP); builder.AddString(_playerName); AddInstanceBytes(builder); builder.AddInt32(PACKET_FOOTER); return(builder.ToBytes()); }
/// <summary> /// Utility function used just to validate login data /// </summary> /// <param name="user">Username to check</param> /// <param name="pass">Password to check</param> private void CheckLogin(string user, string pass) { //return packet PacketBuilder pb = new PacketBuilder(); Logger.Log(String.Format("Username: {0} Password: {1}", user, pass)); //at the begining of our search we haven't found the account bool foundUser = false; foreach (Account account in _server.Accounts) { //when we have found the correct username if (account.Username == user) { foundUser = true; //and the correct password if (account.Password == pass) { //we want to check if the account is already logged in if (account.State == AccountState.LoggedOut) { //if it isn't already logged in then we want to grant access to the requesting client Logger.Log("Login accepted from " + Socket.Client.RemoteEndPoint + " for account " + user); pb = new PacketBuilder() .AddByte((byte)PacketFamily.LOGIN) .AddByte((byte)PacketAction.ACCEPT); //here we're building up a catalogue of characters belonging to the requested account foreach (PlayerCharacter character in account.Characters) { pb = pb.AddByte((byte)character.Name.Length) .AddString(character.Name) .AddByte((byte)character.Level) .AddByte((byte)character.Gender); } account.State = AccountState.LoggedIn; Account = account; } //if it is already logged in then we want to reject the login and let the user know that's the case else { pb = new PacketBuilder() .AddByte((byte)PacketFamily.LOGIN) .AddByte((byte)PacketAction.REJECT) .AddString("Account Logged in somewhere else"); } } //if the password is incorrect then we want to let the user know that's the case else { pb = new PacketBuilder() .AddByte((byte)PacketFamily.LOGIN) .AddByte((byte)PacketAction.REJECT) .AddString("Invalid Password"); } } } //if the username wasn't found in the known accounts then again we want to reject the login //along with the reason why if (!foundUser) { pb = new PacketBuilder() .AddByte((byte)PacketFamily.LOGIN) .AddByte((byte)PacketAction.REJECT) .AddString("Invalid Username"); } //sending the response back to the client whether it's an accepted login or a rejected login Send(pb.Build()); }
private async Task <ICollection <Zone> > HandleZoneListRequest() { var zones = new List <Zone>(); var builder = new PacketBuilder(); builder.AddInt16(0x0005); builder.AddBytes(new byte[26]); var buffer = builder.GetBytes(); await this.networkClient.SendAsync(buffer, buffer.Length); int chunkBufferLength; int chunk; int offset = 0; byte[] chunkBuffer = null; PacketReader reader; do { buffer = await this.networkClient.ReceiveAsync(); reader = new PacketReader(buffer); reader.ReadInt16(); reader.ReadInt16(); chunk = reader.ReadByte(); reader.ReadBytes(7); chunkBufferLength = reader.ReadLittleEndianInt16(); reader.ReadInt16(); if (chunkBuffer == null) { chunkBuffer = new byte[chunkBufferLength]; } offset += reader.CopyBytes(chunkBuffer, offset); builder = new PacketBuilder(); builder.AddInt16(0x000b); builder.AddInt16(0); builder.AddByte((byte)chunk); builder.AddPadding(3); buffer = builder.GetBytes(); await this.networkClient.SendAsync(buffer, buffer.Length); chunk++; } while (offset < (chunkBufferLength)); reader = new PacketReader(chunkBuffer); // Discard the 0x01 at the beginning reader.ReadByte(); while (reader.CanRead()) { var zone = new Zone(); zone.ServerAddress = reader.ReadIPAddress(); zone.ServerPort = reader.ReadUInt16(); reader.ReadBytes(6); zone.Name = reader.ReadString(32); reader.ReadInt16(); zone.IsAdvanced = reader.ReadBoolean(); reader.ReadBytes(29); zone.Description = reader.ReadString(); zones.Add(zone); } return(zones); }
public void AddByteReturnsFalse() { bool result = PacketBuilder.AddByte(HeartbeatPacketBytes[0]); Assert.AreEqual(false, result); }
/// <summary> /// The purpose of this function is to provide one area where the packet data can be handled. /// I was looking to improve this approach by giving each packet its own class that handles /// that type of packet. That would improve the clarity of this class. /// </summary> /// <param name="pkt">The packet to be handled</param> private void HandlePacket(Packet pkt) { try { //packet builder for the return packet PacketBuilder pb; if (pkt.Family == PacketFamily.LOGIN) { if (pkt.Action == PacketAction.REQUEST) { //login request string user = pkt.ReadString(pkt.ReadByte()); string pass = pkt.ReadString(pkt.ReadByte()); pass = Utils.Security.GetHashString(pass + "PROCO304" + user); CheckLogin(user, pass); } } else if (pkt.Family == PacketFamily.CHARACTER) { if (pkt.Action == PacketAction.CREATE) { //for character creation, the first thing we must do is get the requested name string characterName = pkt.ReadString(pkt.ReadByte()); //and then the requested gender byte gender = pkt.ReadByte(); //and initialise whether the name is available or not bool isAvailable = true; foreach (Account account in _server.Accounts) { foreach (Character c in account.Characters) { //loop through every character known to the server if (c.Name == characterName) { //if the name already exists, then the requested name cannot be used isAvailable = false; break; } } } if (!isAvailable) { //relay back to the client to tell them that the name for the character already exists pb = new PacketBuilder(PacketFamily.CHARACTER, PacketAction.ALREADY_EXISTS); string errMsg = "Character already exists"; pb = pb.AddByte((byte)errMsg.Length).AddString(errMsg); Send(pb.Build()); } else { //if they can have the requested character name then we add it to the collection of characters PlayerCharacter character = new PlayerCharacter() { Name = characterName, Dexterity = 0, Strength = 0, Vitality = 0, Intelligence = 0, Gender = (Gender)gender, Facing = 0, EXP = 0, Health = 50, Level = 0, X = 0, Y = 0 }; //and let the client know that they have been accepted pb = new PacketBuilder(PacketFamily.CHARACTER, PacketAction.CREATED); pb = pb.AddByte((byte)characterName.Length) .AddString(characterName) .AddByte((byte)character.Gender); Send(pb.Build()); Account.Characters.Add(character); //save the new character to the database also character.CreateDatabaseEntry(_database, Account.Username); //and then put it out to the server console Logger.Log("Character Created. Name: " + character.Name); } } else if (pkt.Action == PacketAction.DELETE) { int userid = pkt.ReadByte(); PlayerCharacter player = Account.GetCharacter(userid); foreach (Account account in _server.Accounts) { PlayerCharacter toRemove = null; foreach (PlayerCharacter character in account.Characters) { if (character.Name == player.Name) { toRemove = character; } } if (toRemove != null) { account.Characters.Remove(toRemove); } } player.Delete(_database); Account.Characters.Remove(player); Send(pkt); } } else if (pkt.Family == PacketFamily.REGISTER) { if (pkt.Action == PacketAction.REQUEST) { //registering to the game //getting the username string username = pkt.ReadString(pkt.ReadByte()); //getting the password string password = pkt.ReadString(pkt.ReadByte()); //hashing the given password using the username and "PROCO304" as the salt password = Utils.Security.GetHashString(password + "PROCO304" + username); //read the given email string email = pkt.ReadString(pkt.ReadByte()); //and the given name string fullname = pkt.ReadString(pkt.ReadByte()); //output the requested account to the server console Logger.Log(String.Format("Requested username {0} password {1} email {2}", username, password, email)); //initiate the test to see if the account username already exists bool userExists = false; foreach (Account account in _server.Accounts) { if (account.Username == username) { //if the requested account name already exists in the known acccounts list then we need to reject the request //and post back to the client to tell them that the username is already taken. pb = new PacketBuilder(PacketFamily.REGISTER, PacketAction.REJECT); string errMsg = "User already exists"; pb = pb.AddByte((byte)errMsg.Length).AddString(errMsg); Send(pb.Build()); userExists = true; break; } } if (!userExists) { //if the account isn't already taken then we can accept the registration request, //create the new entry in the database and report back to the client to tell them that //their account is ready to go pb = new PacketBuilder(PacketFamily.REGISTER, PacketAction.ACCEPT); pb = pb.AddByte((byte)username.Length).AddString(username); Send(pb.Build()); Account account = new Account(username, password, email, fullname); _server.Accounts.Add(account); account.CreateDatabaseEntry(_database, Socket.Client.RemoteEndPoint.ToString().Split(":")[0]); Logger.Log("Account Created. Username: "******" has gained " + enemy.EXP + " EXP"); } enemy.Contributors = new List <PlayerCharacter>(); //reset position enemy.X = enemy.SpawnX + RNG.Next(-300, 300); enemy.Y = enemy.SpawnY + RNG.Next(-300, 300); enemy.Health = enemy.MaxHealth; //let all clients know of new poisition pb = new PacketBuilder(PacketFamily.ENEMY, PacketAction.MOVE); pb = pb.AddInt(_server.Enemies.IndexOf(enemy)) .AddInt(enemy.X) .AddInt(enemy.Y) .AddByte((byte)enemy.Facing); foreach (Client client in _server.Clients) { client.Send(pb.Build()); } } //notify all clients of new enemy hp pb = new PacketBuilder(PacketFamily.ENEMY, PacketAction.TAKE_DAMAGE) .AddInt(_server.Enemies.IndexOf(enemy)) .AddInt(enemy.Health); foreach (Client client in _server.Clients) { client.Send(pb.Build()); } } } } } else if (pkt.Family == PacketFamily.CONNECTION) { if (pkt.Action == PacketAction.PONG) { //Good client, responded to the PING request. We no longer need the pong. NeedPong = false; } } } catch (Exception e) { Logger.Warn("Packet handling error. Remote endpoint: " + Socket.Client.RemoteEndPoint + "\n\r StackTrace:" + e.StackTrace + "\n\r Message:" + e.Message); } }