public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size) { if (context.Character == null) return; var reader = new PacketReader(data, position, size); reader.BaseStream.Seek(0xC, SeekOrigin.Begin); var channel = reader.ReadUInt32(); var message = reader.ReadUtf16(0x9D3F, 0x44); if (message.StartsWith(PolarisApp.Config.CommandPrefix)) { var valid = false; // Iterate commands foreach (var command in PolarisApp.ConsoleSystem.Commands) { var full = message.Substring(1); // Strip the command chars var args = full.Split(' '); if (command.Names.Any(name => args[0].ToLower() == name.ToLower())) { command.Run(args, args.Length, full, context); valid = true; Logger.WriteCommand(null, "[CMD] {0} issued command {1}", context.User.Username, full); } if (valid) break; } if (!valid) Logger.WriteClient(context, "[CMD] {0} - Command not found", message.Split(' ')[0].Trim('\r')); } else { Logger.Write("[CHT] <{0}> <{1}>", context.Character.Name, message); var writer = new PacketWriter(); writer.WritePlayerHeader((uint) context.User.PlayerId); writer.Write(channel); writer.WriteUtf16(message, 0x9D3F, 0x44); data = writer.ToArray(); foreach (var c in Server.Instance.Clients) { if (c.Character == null || c.CurrentZone != context.CurrentZone) continue; c.SendPacket(0x07, 0x00, 0x44, data); } } }
/// <summary> /// Spawns a client into a map at a given location /// </summary> /// <param name="c">Client to spawn into map</param> /// <param name="location">Location to spawn client at</param> /// <param name="questOveride">If this also sets the quest data, specify the quest name here to load the spawn from the bin rather then generate it.</param> public void SpawnClient(Client c, PSOLocation location, string questOveride = "") { if (Clients.Contains(c)) { return; } // Set area if (questOveride != "") // TODO: This is a temporary hack, fix me!! { var setAreaPacket = File.ReadAllBytes("Resources/quests/" + questOveride + ".bin"); c.SendPacket(0x03, 0x24, 4, setAreaPacket); } else { PacketWriter writer = new PacketWriter(); writer.WriteStruct(new ObjectHeader(3, EntityType.Map)); writer.WriteStruct(new ObjectHeader((uint)c.User.PlayerId, EntityType.Player)); writer.Write(0x1); // 8 Zeros writer.Write(0); // 8 Zeros writer.Write(~(uint)Type); // F4 FF FF FF writer.Write(MapID); // Map ID maybe writer.Write((uint)Flags); writer.Write(GenerationArgs.seed); // 81 8F E6 19 (Maybe seed) writer.Write(VariantID); // Randomgen enable / disable maybe writer.Write(GenerationArgs.xsize); // X Size writer.Write(GenerationArgs.ysize); // Y Size writer.Write(1); writer.Write(1); writer.Write(~0); // FF FF FF FF FF FF FF FF writer.Write(0x301); c.SendPacket(0x3, 0x0, 0x0, writer.ToArray()); } if (c.CurrentZone != null) { c.CurrentZone.RemoveClient(c); } var setPlayerId = new PacketWriter(); setPlayerId.WritePlayerHeader((uint)c.User.PlayerId); c.SendPacket(0x06, 0x00, 0, setPlayerId.ToArray()); // Spawn Character c.SendPacket(new CharacterSpawnPacket(c.Character, location)); c.CurrentLocation = location; c.CurrentZone = this; // Objects foreach (PSOObject obj in Objects) { c.SendPacket(0x08, 0x0B, 0x0, obj.GenerateSpawnBlob()); } // NPCs foreach (PSONPC npc in NPCs) { c.SendPacket(0x08, 0xC, 0x4, npc.GenerateSpawnBlob()); } // Spawn for others, Spawn others for me CharacterSpawnPacket spawnMe = new CharacterSpawnPacket(c.Character, location, false); foreach (Client other in Clients) { other.SendPacket(spawnMe); c.SendPacket(new CharacterSpawnPacket(other.Character, other.CurrentLocation, false)); } // Unlock Controls c.SendPacket(new NoPayloadPacket(0x03, 0x2B)); // Inital spawn only, move this! Clients.Add(c); Logger.Write("[MAP] {0} has spawned in {1}.", c.User.Username, Name); if (InstanceName != null && ZoneManager.Instance.playerCounter.ContainsKey(InstanceName)) { ZoneManager.Instance.playerCounter[InstanceName] += 1; } }