public void TestReadonlyCheck() { byte[] bytes = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; string text = "Hello World!"; using var write = new PacketBuffer(); write.WriteUInt16(0x3f7a); write.WriteDateTime(DateTime.Now); using var read = new PacketBuffer(write.GetBuffer()); Assert.ThrowsException <InvalidOperationException>(() => read.WriteBoolean(true)); Assert.ThrowsException <InvalidOperationException>(() => read.WriteByte(0x7f)); Assert.ThrowsException <InvalidOperationException>(() => read.WriteUInt16(0x900a)); Assert.ThrowsException <InvalidOperationException>(() => read.WriteInt32(0x6502a14c)); Assert.ThrowsException <InvalidOperationException>(() => read.WriteInt64(0x1a41a174a64c91aa)); Assert.ThrowsException <InvalidOperationException>(() => read.WriteDateTime(default));
public Client(IServiceProvider serviceProvider, ConnectionsService connections, PacketService packets, ILogger <Client> logger, PacketStream stream, CancellationToken ct) { this.serviceProvider = serviceProvider; this.connections = connections; this.packets = packets; this.logger = logger; this.stream = stream; this.ct = ct; sendQueue = new JobQueue <Packet, bool>(async(packet, dispose) => { try { using var buffer = new PacketBuffer(); packet.WritePacket(buffer, PacketRole.Server); await stream.WriteAsync(packet.Id, buffer.GetBuffer()).ConfigureAwait(false); logger.LogInformation("Successfully sent packet {0} to session {1}", packet, SessionId.ToString("x8")); } catch (IOException ex) when(ex.InnerException is SocketException socketEx) { await DisposeAsync(waitForHandling: false).ConfigureAwait(false); if (socketEx.SocketErrorCode == SocketError.TimedOut) { logger.LogInformation("Session {0} timed out", SessionId.ToString("x8")); } else { logger.LogInformation("Session {0} lost connection", SessionId.ToString("x8")); } } catch (Exception ex) { await DisposeAsync(waitForHandling: false).ConfigureAwait(false); logger.LogCritical(ex, "Unexpected exception occurred while sending packet {0} to session {1}", packet.Id.ToString("x2"), SessionId.ToString("x8")); } finally { if (dispose) { (packet as IDisposable)?.Dispose(); } } }); handler = Listen(); }
public void SendEntities(User user) { foreach (var npc in NpcTalk) { var buffer = new PacketBuffer(0x8, user); buffer.WriteUInt16(npc.EntityId); buffer.WriteUInt16(2); // Type? 2 = NPC buffer.WriteUInt32((uint)npc.Type); buffer.WriteUInt32(0); // ? buffer.WriteUInt16(0); // ? var pos = PointObjects.FirstOrDefault(x => x.Id == npc.PosId); if (pos != null) { buffer.WriteUInt16((ushort)pos.X); buffer.WriteUInt16((ushort)pos.Y); buffer.WriteUInt16((ushort)pos.X); buffer.WriteUInt16((ushort)pos.Y); } else { Program.logger.Error("------ Entity position {0} not found for NPC {1} in map {2} ({3})", npc.PosId, npc.Type, Name, Id); buffer.WriteUInt16(0); buffer.WriteUInt16(0); buffer.WriteUInt16(0); buffer.WriteUInt16(0); } buffer.WriteString(Methods.Utf8Convert(Data.CharacterInfo[npc.Type].Name)); buffer.WriteByte(0x00); buffer.WriteHexString("00 80 00 00 00 00 00 00 00 00 00 00"); // ? buffer.WriteUInt16((ushort)npc.PosId); buffer.WriteUInt16((ushort)npc.HeadMarkType); // Head marking buffer.WriteUInt16(0); // ? Program.logger.Debug("Sending entity packet: {0}", Util.ByteToHex(buffer.GetBuffer())); buffer.Send(); } }
// 0x05 public static void HandleSelect2(User user, byte[] packet) { var p1 = new PacketBuffer(0x2E29, user); p1.WriteHexString("00 00 00"); p1.Send(); var full = new List <byte>(); var player = new PacketBuffer(0x07, user); player.WriteUInt16(user.Character.EntityId); // wrong type? //player.WriteHexString("01 00 04 00 09 04 01 00 08 00 00 00 B5 03 B4 08 B5 03 B4 08 64 75 72 61 67 6F 6E 31 32 34 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 00 60 00 00 00 F7 1A 00 00 29 1B 00 00 00 00 00 00 09 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"); player.WriteUInt16(1); // ? (user.Character.FType); player.WriteUInt16(user.Character.Type); player.WriteByte((byte)user.Character.Hair); player.WriteByte((byte)user.Character.Type); player.WriteUInt16(user.Character.Level); // ? player.WriteUInt32(8); // ? player.WriteUInt16(user.Character.X); player.WriteUInt16(user.Character.Y); player.WriteUInt16(user.Character.X); player.WriteUInt16(user.Character.Y); player.WriteString(user.Character.Name); player.WriteHexString("00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 00 60 00 00 00"); // equip player.WriteUInt32(0x1AF7); // equip player.WriteUInt32(0x1B29); player.WriteHexString("00 00 00 00 00 00 09 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"); Program.logger.Info("GS Login player packet: {0}", Util.ByteToHex(player.GetBuffer())); full.AddRange(player.GetPacket()); var unk1 = new PacketBuffer(0x135, user); full.AddRange(unk1.GetPacket()); var unk2 = new PacketBuffer(0x25C, user); full.AddRange(unk2.GetPacket()); var unk5 = new PacketBuffer(0x3A6, user); unk5.WriteHexString("00 00 00 00 00 00 00 00 00 00 00 00"); full.AddRange(unk5.GetPacket()); var unk6 = new PacketBuffer(0x3A5, user); unk6.WriteUInt16(user.Character.EntityId); unk6.WriteHexString("00 00"); full.AddRange(unk6.GetPacket()); var unk7 = new PacketBuffer(0x325, user); unk7.WriteHexString("AD E6 76 CE"); full.AddRange(unk7.GetPacket()); var time = new PacketBuffer(0x477, user); time.WriteHexString("00 00 00 00 00 00 00 00 00 00 00 00"); time.WriteUInt64(Methods.DateTimeToUnix(DateTime.UtcNow)); full.AddRange(time.GetPacket()); var unk9 = new PacketBuffer(0x4CC, user); unk9.WriteHexString("00 00 00 00"); full.AddRange(unk9.GetPacket()); var healthStatus = new PacketBuffer(0x24, user); healthStatus.WriteHexString("29 00 00 00"); full.AddRange(healthStatus.GetPacket()); var manaStatus = new PacketBuffer(0x25, user); manaStatus.WriteHexString("05 00 00 00"); full.AddRange(manaStatus.GetPacket()); user.Socket.Send(full.ToArray()); Data.Maps[user.Character.Map].SendEntities(user); }
// 0x9C // 18 00 9C 00 00 00 63 00 9A // E2 6E F7 05 00 00 00 00 F3 5F 00 00 02 public static void EnterMap(User user, InPacket inPacket) { var enterId = inPacket.ReadUInt(); var foundUser = Program._users.Where(x => x.Value != null && x.Value.Character != null && x.Value.Character.Id == enterId).FirstOrDefault(); if (foundUser.Value == null) { throw new Exception("Zone change user not found"); } //Program.logger.Info("Old key [user]: {0}", Util.ByteToHex(user.ClientSession.Key)); //Program.logger.Info("Old key [foundUser.ClientSession]: {0}", Util.ByteToHex(foundUser.Value.ClientSession.Key)); var currSock = user.Socket; var currClientSession = user.ClientSession; //Program.logger.Info("Found user socket: {0} / New: {1}", foundUser.Value.Socket.RemoteEndPoint.ToString(), user.Socket.RemoteEndPoint.ToString()); Program._users[user.Socket.RemoteEndPoint.ToString()] = foundUser.Value; user = Program._users[user.Socket.RemoteEndPoint.ToString()]; user.Socket = currSock; user.ClientSession = currClientSession; user.ClientSession.Client = user; user.ServerSession = new SessionInfo { Client = user }; Program._users.Remove(foundUser.Key); var character = user.Character; Program.logger.Info("{0} - Enter Zone: {1} ({2})", character.Name, Data.Maps[character.Map].Name, character.Map); character.EntityId = ++Program.EntityId; { var notifyEntityId = new PacketBuffer(0x3D1, user); notifyEntityId.WriteUInt32(character.EntityId); notifyEntityId.WriteHexString("00 00 00 00 00 00 00 00"); notifyEntityId.Send(); } var charInfo = new List <byte>(); { var unk1 = new PacketBuffer(0x377, user); unk1.WriteHexString("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 A8 36 00 00 00 00 00 00 00 00 17 B7 51 38"); charInfo.AddRange(unk1.GetPacket()); } { var unk2 = new PacketBuffer(0x376, user); unk2.WriteHexString("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 A8 36 00 00 00 00 00 00 00 00 17 B7 51 38"); charInfo.AddRange(unk2.GetPacket()); } { var unk3 = new PacketBuffer(0x3D7, user); unk3.WriteHexString("01 00 00 00 00 90 85 D5 41 00 00 00 00 00 00 00 00 00 00 00 00 77 86 45 5B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"); charInfo.AddRange(unk3.GetPacket()); } { var unk4 = new PacketBuffer(0x2A4, user); unk4.WriteUInt16(0); charInfo.AddRange(unk4.GetPacket()); } { var unk5 = new PacketBuffer(0x3E4, user); unk5.WriteUInt32(3); charInfo.AddRange(unk5.GetPacket()); } { var unk6 = new PacketBuffer(0x3E7, user); unk6.WriteUInt16(character.EntityId); unk6.WriteHexString("00 00 00 00 00 00 00 00 00 00 00"); charInfo.AddRange(unk6.GetPacket()); } { var unk7 = new PacketBuffer(0x3EA, user); unk7.WriteUInt16(0); charInfo.AddRange(unk7.GetPacket()); } { var unk8 = new PacketBuffer(0x4CC, user); unk8.WriteHexString("00 00 00 00"); charInfo.AddRange(unk8.GetPacket()); } { var unk9 = new PacketBuffer(0x1B5, user); unk9.WriteUInt16(character.EntityId); unk9.WriteUInt16(character.X); unk9.WriteUInt16(character.Y); unk9.WriteHexString("00 00 00 00 00"); charInfo.AddRange(unk9.GetPacket()); } { var unk10 = new PacketBuffer(0x376, user); unk10.WriteHexString("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E2 4F 4D 3E 00 00 00 00 00 00 00 00 17 B7 51 38"); charInfo.AddRange(unk10.GetPacket()); } { var unk11 = new PacketBuffer(0x377, user); unk11.WriteHexString("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E2 4F 4D 3E 00 00 00 00 00 00 00 00 17 B7 51 38"); charInfo.AddRange(unk11.GetPacket()); } { var notifyEntity = new PacketBuffer(0x09, user); notifyEntity.WriteUInt16(character.EntityId); notifyEntity.WriteUInt16(1); notifyEntity.WriteUInt16(character.Job); notifyEntity.WriteByte((byte)character.Hair); notifyEntity.WriteByte((byte)character.Type); notifyEntity.WriteUInt16(character.Level); notifyEntity.WriteUInt32(8); // ? notifyEntity.WriteUInt16(character.X); notifyEntity.WriteUInt16(character.Y); notifyEntity.WriteUInt16(character.X); notifyEntity.WriteUInt16(character.Y); notifyEntity.WriteString(character.Name); notifyEntity.WriteUInt32(0x00); notifyEntity.WriteUInt32(0x00); // ? notifyEntity.WriteUInt32(0x01); // ? notifyEntity.WriteUInt32(0); // ? notifyEntity.WriteUInt32(0); // ? notifyEntity.WriteUInt16(0); // ???? notifyEntity.WriteByte((byte)character.Job); /* * notifyEntity.WriteUInt32(63); * notifyEntity.WriteUInt32(6903); // Item * notifyEntity.WriteUInt32(6953); // Item * notifyEntity.WriteUInt32(0); */ notifyEntity.WriteHexString("00 00 00 00 63 00 00 00 F6 45 00 00 90 28 01 00 14 1B 00 00 46 1B 00 00 00 00 00 00 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"); Program.logger.Info("Self entity packet: {0}", Util.ByteToHex(notifyEntity.GetBuffer())); charInfo.AddRange(notifyEntity.GetPacket()); } { var unk12 = new PacketBuffer(0x25C, user); charInfo.AddRange(unk12.GetPacket()); } { var unk13 = new PacketBuffer(0x377, user); unk13.WriteHexString("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 CE 4C 3E 00 00 00 00 00 00 00 00 17 B7 51 38"); charInfo.AddRange(unk13.GetPacket()); } { var unk14 = new PacketBuffer(0x376, user); unk14.WriteHexString("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 CE 4C 3E 00 00 00 00 00 00 00 00 17 B7 51 38"); charInfo.AddRange(unk14.GetPacket()); } { var unk15 = new PacketBuffer(0x42C, user); unk15.WriteHexString("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"); charInfo.AddRange(unk15.GetPacket()); } { var unk16 = new PacketBuffer(0x9D, user); unk16.WriteUInt32(0); charInfo.AddRange(unk16.GetPacket()); } { var healthStatus = new PacketBuffer(0x24, user); healthStatus.WriteHexString("29 00 00 00"); charInfo.AddRange(healthStatus.GetPacket()); } { var manaStatus = new PacketBuffer(0x25, user); manaStatus.WriteHexString("05 00 00 00"); charInfo.AddRange(manaStatus.GetPacket()); } user.Socket.Send(charInfo.ToArray()); { var p1 = new PacketBuffer(0x1D8, user); p1.WriteUInt16(character.EntityId); p1.WriteByte(0x2E); p1.Send(); } }
public static void Handle(User user, byte[] packet) { var numChars = 0; try { using (MySqlCommand cmd = Program._MySQLConn.CreateCommand()) { cmd.CommandText = "SELECT COUNT(*) FROM characters WHERE user = @userid AND authority != 2;"; cmd.Parameters.AddWithValue("@userid", Methods.CleanString(user.Id.ToString())); numChars = Convert.ToInt32(cmd.ExecuteScalar()); cmd.Dispose(); } } catch (Exception ex) { Program.logger.Error(ex, "Database error: "); return; } user.NumChars = numChars; PacketBuffer chars = new PacketBuffer(0x7D2, user); chars.WriteByte((byte)numChars); // Number of characters if (numChars > 0) { byte slotNum = 0; using (MySqlCommand cmd = Program._MySQLConn.CreateCommand()) { cmd.CommandText = "SELECT * FROM characters WHERE user = @userid AND authority != 2 LIMIT 12;"; cmd.Parameters.AddWithValue("@userid", Methods.CleanString(user.Id.ToString())); using (MySqlDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { chars.WriteUInt32(reader.GetUInt32("id")); // Character ID chars.WriteInt32(0); // probably part of int64? chars.WriteByte(slotNum); // Index // 16 bytes maximum, but 20 is fine var name = Methods.Utf8Convert(reader.GetString("name")); chars.WriteString(name, 20); // Job(1) // 0x09 = (int)9 : Paula chars.WriteUInt16(reader.GetUInt16("job")); // ? // Display job? chars.WriteUInt16(0); // FType (power/magic/sense/charm) chars.WriteByte((byte)reader.GetInt32("ftype")); // (byte)Constants.CharacterTypes[9]); // Type(2) // 0x09 = (int)9 : Paula chars.WriteByte((byte)reader.GetInt32("type")); // 0x09 // ? // [Dev]Raymonf = 01 0C chars.WriteHexString("00 01"); // hair color // 0x0A chars.WriteUInt16((byte)reader.GetUInt16("hair")); // Galders chars.WriteUInt32((byte)reader.GetUInt32("money")); // Level chars.WriteUInt16(reader.GetUInt16("level")); // Hat (head item) // Rookie Hat chars.WriteUInt32(4030); // Weapon (sword) // Rookie Sword chars.WriteUInt32(3030); // Shield // Rookie Shield //chars.WriteUInt(6530); chars.WriteUInt32(0); // paula can't wear these // Innerwear chars.WriteUInt32(0); // Accessory 1 // Duckling Keychain chars.WriteUInt32(19241); // Bear's ears chars.WriteInt32(6932); // Bear's tail chars.WriteInt32(6982); // Drill // Flicker Drill chars.WriteUInt32(19901); // Pet // Peng chars.WriteUInt32(1642); // Accessory 2 // Tin tiger amulet chars.WriteUInt32(440004); //////// Unchartered territories // ?? chars.WriteUInt32(0); // ?? chars.WriteUInt32(0); // ?? chars.WriteUInt32(0); // ??? chars.WriteUInt32(0); // ??? chars.WriteUInt32(0); // ??? chars.WriteUInt32(0); // ??? chars.WriteUInt32(0); // ??? chars.WriteUInt32(0); // Ammo? chars.WriteUInt32(5500); // Cape chars.WriteUInt32(35082); // Sprint chars.WriteUInt32(888887); // TODO // ? chars.WriteHexString("02 01 00"); // 3rd job chars.WriteUInt16(22); chars.WriteUInt16(29); chars.WriteHexString("00 01 00 00 00 00"); //chars.WriteByte(0x00); chars.WriteUInt32(0); chars.WriteUInt32(0); chars.WriteUInt32(0); chars.WriteHexString("00 00"); slotNum++; } } } } chars.WriteHexString("00 00 00 00 00 00 00 00 00 00 00"); chars.WriteByte((byte)user.SlotsAllowed); // Number of character slots Program.logger.Debug("Character select packet: {0}", Util.ByteToHex(chars.GetBuffer())); chars.Send(); }
public static void Handle(User user, byte[] packet) { Program.logger.Debug("Received packet: {0}", Util.ByteToHex(packet)); var nameBytes = Methods.ReadTerminatedStringToBytes(packet); var startIdx = nameBytes.Length + 1; byte type = packet[startIdx]; // 0x09 byte job = packet[startIdx + 3]; // 0x09 byte hairColor = packet[startIdx + 2]; // 0x0A - hair color int stat_p = packet[startIdx + 5]; int stat_m = packet[startIdx + 6]; int stat_s = packet[startIdx + 7]; int stat_c = packet[startIdx + 8]; var name = Constants.Encoding.GetString(nameBytes); // Check the name try { using (MySqlCommand cmd = Program._MySQLConn.CreateCommand()) { cmd.CommandText = "SELECT COUNT(*) FROM characters WHERE name LIKE @name AND authority != 2;"; cmd.Parameters.AddWithValue("@name", Methods.CleanString(name)); if (Convert.ToInt32(cmd.ExecuteScalar()) >= 1) { var fail = new PacketBuffer(0x7D7, user); fail.WriteUInt32(0x3FF); fail.Send(); cmd.Dispose(); return; } cmd.Dispose(); } } catch (Exception ex) { Program.logger.Error(ex, "Database error: "); return; } uint newCharId = 0; using (MySqlCommand cmd = Program._MySQLConn.CreateCommand()) { cmd.CommandText = "INSERT INTO characters (user, name, job, type, ftype, hair, build) VALUES (@userid, @charname, @job, @type, @ftype, @hair, @build); select last_insert_id();"; cmd.Parameters.AddWithValue("@userid", user.Id); cmd.Parameters.AddWithValue("@charname", name); cmd.Parameters.AddWithValue("@job", job); cmd.Parameters.AddWithValue("@type", type); cmd.Parameters.AddWithValue("@ftype", Constants.CharacterTypes[type]); cmd.Parameters.AddWithValue("@hair", hairColor); cmd.Parameters.AddWithValue("@build", stat_p + "," + stat_m + "," + stat_s + "," + stat_c); newCharId = Convert.ToUInt32(cmd.ExecuteScalar()); } Program.logger.Debug("New character ID: {0}", newCharId); user.NumChars++; PacketBuffer res = new PacketBuffer(0x7D8, user); res.WriteUInt32(newCharId); // Character ID res.WriteInt32(0); // probably part of int64? res.WriteByte((byte)(user.NumChars - 1)); // Index // 16 bytes maximum, but 20 is fine res.WriteString(name, 20); // Job(1) // 0x09 = (int)9 : Paula res.WriteUInt16(job); // ? // Display job? res.WriteUInt16(0); // FType (power/magic/sense/charm) res.WriteByte((byte)Constants.CharacterTypes[type]); // Type(2) // 0x09 = (int)9 : Paula res.WriteByte((byte)type); // 0x09 // ? // [Dev]Raymonf = 0C 03 res.WriteHexString("00 01"); // hair color // 0x0A res.WriteUInt16(hairColor); // Galders res.WriteUInt32(0); // Level res.WriteUInt16(1); // Hat (head item) // Rookie Hat res.WriteUInt32(0); // Weapon (sword) // Rookie Sword res.WriteUInt32(0); // Shield // Rookie Shield res.WriteUInt32(0); // ?? res.WriteUInt32(0); // Accessory 1 // Jeweled Egg 40 res.WriteUInt32(0); // Bear's ears res.WriteInt32(6932); // Bear's tail res.WriteInt32(6982); // Flicker Drill res.WriteUInt32(0); // ?? res.WriteUInt32(0); // Accessory 2 // Pocket pouch res.WriteUInt32(7000); // ?? res.WriteUInt32(0); // ?? res.WriteUInt32(0); // ?? res.WriteUInt32(0); // TODO res.WriteHexString("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"); Program.logger.Debug("Create packet: {0}", Util.ByteToHex(res.GetBuffer())); res.Send(); }