public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size) { if (context.User == null || context.Character == null) return; // Looks/Jobs if (size > 0) { var reader = new PacketReader(data); reader.BaseStream.Seek(0x38, SeekOrigin.Begin); context.Character.Looks = reader.ReadStruct<Character.LooksParam>(); context.Character.Jobs = reader.ReadStruct<Character.JobParam>(); using(var db = new PolarisEf()) db.ChangeTracker.DetectChanges(); } Map lobbyMap = ZoneManager.Instance.MapFromInstance("lobby", "lobby"); lobbyMap.SpawnClient(context, lobbyMap.GetDefaultLocation(), "lobby"); // Unlock Controls context.SendPacket(new NoPayloadPacket(0x03, 0x2B)); //context.SendPacket(File.ReadAllBytes("testbed/237.23-7.210.189.208.30.bin")); // Give a blank palette context.SendPacket(new PalettePacket()); // memset packet - Enables menus // Also holds event items and likely other stuff too var memSetPacket = File.ReadAllBytes("Resources/setMemoryPacket.bin"); context.SendPacket(memSetPacket); }
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size) { var reader = new PacketReader(data, position, size); var charId = reader.ReadUInt32(); if (context.User == null) return; if (context.Character == null) // On character create, this is already set. { using (var db = new PolarisEf()) { var character = db.Characters.Find((int)charId); if (character == null || character.Player.PlayerId != context.User.PlayerId) return; context.Character = character; } } // Transition to the loading screen context.SendPacket(new NoPayloadPacket(0x3, 0x4)); // TODO Set area, Set character, possibly more. See PolarisLegacy for more. }
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size) { var reader = new PacketReader(data); var id = reader.ReadInt32(); Logger.Write("[CHR] {0} is deleting character with ID {1}", context.User.Username, id); // Delete Character using (var db = new PolarisEf()) { foreach (var character in db.Characters) if (character.CharacterId == id) { db.Characters.Remove(character); db.ChangeTracker.DetectChanges(); break; } // Detect the deletion and save the Database if (db.ChangeTracker.HasChanges()) db.SaveChanges(); } // Disconnect for now // TODO: What do we do after a deletion? context.Socket.Close(); }
public PSOObject[] GetObjectsForZone(string zone) { if (zone == "tpmap") // Return empty object array for an tp'd map for now (We spawn in a teleporter manually) { return new PSOObject[0]; } if (!zoneObjects.ContainsKey(zone)) { Dictionary<ulong, PSOObject> objects = new Dictionary<ulong, PSOObject>(); // Collect from db using (var db = new PolarisEf()) { var dbObjects = from dbo in db.GameObjects where dbo.ZoneName == zone select dbo; foreach(var dbObject in dbObjects) { var newObject = PSOObject.FromDBObject(dbObject); objects.Add(newObject.Header.ID, newObject); allTheObjects.Add(newObject.Header.ID, newObject); Logger.WriteInternal("[OBJ] Loaded object {0} for zone {1} from the DB.", newObject.Name, zone); } } // Fallback if (objects.Count < 1 && Directory.Exists("Resources/objects/" + zone)) { Logger.WriteWarning("[OBJ] No objects defined for zone {0} in the database, falling back to filesystem!", zone); var objectPaths = Directory.GetFiles("Resources/objects/" + zone); Array.Sort(objectPaths); foreach (var path in objectPaths) { if (Path.GetExtension(path) == ".bin") { var newObject = PSOObject.FromPacketBin(File.ReadAllBytes(path)); objects.Add(newObject.Header.ID, newObject); allTheObjects.Add(newObject.Header.ID, newObject); Logger.WriteInternal("[OBJ] Loaded object ID {0} with name {1} pos: ({2}, {3}, {4})", newObject.Header.ID, newObject.Name, newObject.Position.PosX, newObject.Position.PosY, newObject.Position.PosZ); } else if (Path.GetExtension(path) == ".json") { var newObject = JsonConvert.DeserializeObject<PSOObject>(File.ReadAllText(path)); objects.Add(newObject.Header.ID, newObject); allTheObjects.Add(newObject.Header.ID, newObject); Logger.WriteInternal("[OBJ] Loaded object ID {0} with name {1} pos: ({2}, {3}, {4})", newObject.Header.ID, newObject.Name, newObject.Position.PosX, newObject.Position.PosY, newObject.Position.PosZ); } } } zoneObjects.Add(zone, objects); } return zoneObjects[zone].Values.ToArray(); }
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size) { if (context.User == null) return; var writer = new PacketWriter(); using (var db = new PolarisEf()) { var chars = db.Characters .Where(w => w.Player.PlayerId == context.User.PlayerId) .OrderBy(o => o.CharacterId) // TODO: Order by last played .Select(s => s); writer.Write((uint)chars.Count()); // Number of characters for (var i = 0; i < 0x4; i++) // Whatever this is writer.Write((byte)0); foreach (var ch in chars) { writer.Write((uint)ch.CharacterId); writer.Write((uint)context.User.PlayerId); for (var i = 0; i < 0x10; i++) writer.Write((byte)0); writer.WriteFixedLengthUtf16(ch.Name, 16); writer.Write((uint)0); writer.WriteStruct(ch.Looks); // Note: Pre-Episode 4 created looks doesn't seem to work anymore writer.WriteStruct(ch.Jobs); for (var i = 0; i < 0xFC; i++) writer.Write((byte)0); } } // Ninji note: This packet may be followed by extra data, // after a fixed-length array of character data structures. // Needs more investigation at some point. // --- // CK note: Extra data is likely current equipment, playtime, etc. // All of that data is currently unaccounted for at the moment. context.SendPacket(0x11, 0x03, 0, writer.ToArray()); }
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size) { if (context.User == null) return; var writer = new PacketWriter(); using (var db = new PolarisEf()) { var chars = from c in db.Characters where c.Player.PlayerId == context.User.PlayerId select c; writer.Write((uint)chars.Count()); foreach (var ch in chars) { writer.Write((uint)ch.CharacterId); writer.Write((uint)context.User.PlayerId); for (var i = 0; i < 0xC; i++) writer.Write((byte)0); writer.WriteFixedLengthUtf16(ch.Name, 16); writer.Write((uint)0); writer.WriteStruct(ch.Looks); writer.WriteStruct(ch.Jobs); for (var i = 0; i < 0x44; i++) writer.Write((byte)0); } } // Ninji note: This packet may be followed by extra data, // after a fixed-length array of character data structures. // Needs more investigation at some point. // --- // CK note: Extra data is likely current equipment, playtime, etc. // All of that data is currently unaccounted for at the moment. context.SendPacket(0x11, 0x03, 0, writer.ToArray()); }
public void Start() { Logger.WriteInternal("Server starting at " + DateTime.Now); Server = new Server(); Config.Load(); PacketHandlers.LoadPacketHandlers(); Logger.WriteInternal("[DB ] Loading database..."); using (var db = new PolarisEf()) { db.SetupDB(); } for (var i = 0; i < 10; i++) QueryServers.Add(new QueryServer(QueryMode.ShipList, 12099 + (100 * i))); Server.Run(); }
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size) { PacketReader reader = new PacketReader(data); reader.ReadBytes(12); // Padding MAYBE??????????? ObjectHeader srcObject = reader.ReadStruct<ObjectHeader>(); byte[] someBytes = reader.ReadBytes(4); // Dunno what this is yet. ObjectHeader dstObject = reader.ReadStruct<ObjectHeader>(); // Could be wrong reader.ReadBytes(16); // Not sure what this is yet string command = reader.ReadAscii(0xD711, 0xCA); PSOObject srcObj; if(srcObject.EntityType == EntityType.Object) { srcObj = ObjectManager.Instance.getObjectByID(context.CurrentZone.Name, srcObject.ID); } else if(srcObject.EntityType == EntityType.Player) { srcObj = new PSOObject(); srcObj.Header = srcObject; srcObj.Name = "Player"; } else { srcObj = null; } Logger.WriteInternal("[OBJ] {0} (ID {1}) <{2}> --> Ent {3} (ID {4})", srcObj.Name, srcObj.Header.ID, command, (EntityType)dstObject.EntityType, dstObject.ID); // TODO: Delete this code and do this COMPLETELY correctly!!! if (command == "Transfer" && context.CurrentZone.Name == "lobby") { // Try and get the teleport definition for the object... using (var db = new PolarisEf()) { db.Configuration.AutoDetectChangesEnabled = true; var teleporterEndpoint = db.Teleports.Find("lobby", (int)srcObject.ID); if (teleporterEndpoint == null) { Logger.WriteError("[OBJ] Teleporter for {0} in {1} does not contain a destination!", srcObj.Header.ID, "lobby"); // Teleport Player to default point context.SendPacket(new TeleportTransferPacket(srcObj, new PSOLocation(0f, 1f, 0f, -0.000031f, -0.417969f, 0.000031f, 134.375f))); // Unhide player context.SendPacket(new ObjectActionPacket(dstObject, srcObject, new ObjectHeader(), new ObjectHeader(), "Forwarded")); } else { PSOLocation endpointLocation = new PSOLocation() { RotX = teleporterEndpoint.RotX, RotY = teleporterEndpoint.RotY, RotZ = teleporterEndpoint.RotZ, RotW = teleporterEndpoint.RotW, PosX = teleporterEndpoint.PosX, PosY = teleporterEndpoint.PosY, PosZ = teleporterEndpoint.PosZ, }; // Teleport Player context.SendPacket(new TeleportTransferPacket(srcObj, endpointLocation)); // Unhide player context.SendPacket(new ObjectActionPacket(dstObject, srcObject, new ObjectHeader(), new ObjectHeader(), "Forwarded")); } } } if (command == "READY") { context.SendPacket(new ObjectActionPacket(new ObjectHeader((uint)context.User.PlayerId, EntityType.Player), srcObj.Header, srcObj.Header, new ObjectHeader(), "FavsNeutral")); context.SendPacket(new ObjectActionPacket(new ObjectHeader((uint)context.User.PlayerId, EntityType.Player), srcObj.Header, srcObj.Header, new ObjectHeader(), "AP")); // Short for Appear, Thanks Zapero! } if (command == "Sit") { foreach (var client in Server.Instance.Clients) { if (client.Character == null || client == context) continue; client.SendPacket(new ObjectActionPacket(new ObjectHeader((uint)client.User.PlayerId, EntityType.Player), srcObj.Header, new ObjectHeader(dstObject.ID, EntityType.Player), new ObjectHeader(), "SitSuccess")); } } }
public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size) { var reader = new PacketReader(data, position, size); reader.BaseStream.Seek(0x2C, SeekOrigin.Current); var macCount = reader.ReadMagic(0x5E6, 107); reader.BaseStream.Seek(0x1C * macCount, SeekOrigin.Current); reader.BaseStream.Seek(0x138, SeekOrigin.Current); var username = reader.ReadFixedLengthAscii(64); var password = reader.ReadFixedLengthAscii(64); // What am I doing here even using (var db = new PolarisEf()) { var users = from u in db.Players where u.Username.ToLower().Equals(username.ToLower()) select u; var error = ""; Player user; if (!users.Any()) { // Check if there is an empty field if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password)) { error = "Username and password fields must not be empty."; user = null; } // Check for special characters else if (!Regex.IsMatch(username, "^[a-zA-Z0-9 ]*$", RegexOptions.IgnoreCase)) { error = "Username must not contain special characters.\nPlease use letters and numbers only."; user = null; } else // We're all good! { // Insert new player into database user = new Player { Username = username.ToLower(), Password = BCrypt.Net.BCrypt.HashPassword(password), Nickname = username.ToLower(), // Since we can't display the nickname prompt yet, just default it to the username SettingsIni = File.ReadAllText("Resources/settings.txt") }; db.Players.Add(user); db.SaveChanges(); // context.SendPacket(0x11, 0x1e, 0x0, new byte[0x44]); // Request nickname } } else { user = users.First(); if (!BCrypt.Net.BCrypt.Verify(password, user.Password)) { error = "Incorrect password."; user = null; } } /* Mystery packet var mystery = new PacketWriter(); mystery.Write((uint)100); SendPacket(0x11, 0x49, 0, mystery.ToArray()); */ // Login response packet context.SendPacket(new LoginDataPacket("Polaris Block 1", error, (user == null) ? (uint)0 : (uint)user.PlayerId)); if (user == null) return; // Settings packet var settings = new PacketWriter(); settings.WriteAscii(user.SettingsIni, 0x54AF, 0x100); context.SendPacket(0x2B, 2, 4, settings.ToArray()); context.User = user; } if (PolarisApp.Config.motd != "") { context.SendPacket(new SystemMessagePacket(PolarisApp.Config.motd, SystemMessagePacket.MessageType.AdminMessageInstant)); } }
internal PSONPC[] getNPCSForZone(string zone) { List<PSONPC> npcs = new List<PSONPC>(); using (var db = new PolarisEf()) { var dbNpcs = from n in db.NPCs where n.ZoneName == zone select n; foreach (NPC npc in dbNpcs) { PSONPC dNpc = new PSONPC(); dNpc.Header = new ObjectHeader((uint)npc.EntityID, EntityType.Object); dNpc.Position = new PSOLocation(npc.RotX, npc.RotY, npc.RotZ, npc.RotW, npc.PosX, npc.PosY, npc.PosZ); dNpc.Name = npc.NPCName; npcs.Add(dNpc); if (!zoneObjects[zone].ContainsKey(dNpc.Header.ID)) { zoneObjects[zone].Add(dNpc.Header.ID, dNpc); } if (!allTheObjects.ContainsKey(dNpc.Header.ID)) allTheObjects.Add(dNpc.Header.ID, dNpc); } } return npcs.ToArray(); }
private void ImportObjects(string[] args, int length, string full, Client client) { string zone = args[1]; string folder = args[2]; var packetList = Directory.GetFiles(folder); Array.Sort(packetList); List<GameObject> newObjects = new List<GameObject>(); foreach (var path in packetList) { var data = File.ReadAllBytes(path); PacketReader reader = new PacketReader(data); PacketHeader header = reader.ReadStruct<PacketHeader>(); if (header.Type != 0x8 || header.Subtype != 0xB) { Logger.WriteWarning("[WRN] File {0} not an Object spawn packet, skipping.", path); continue; } GameObject newObj = new GameObject(); newObj.ObjectID = (int)reader.ReadStruct<ObjectHeader>().ID; var pos = reader.ReadEntityPosition(); newObj.RotX = pos.RotX; newObj.RotY = pos.RotY; newObj.RotZ = pos.RotZ; newObj.RotW = pos.RotW; newObj.PosX = pos.PosX; newObj.PosY = pos.PosY; newObj.PosZ = pos.PosZ; reader.ReadInt16(); newObj.ObjectName = reader.ReadFixedLengthAscii(0x2C); var objHeader = reader.ReadStruct<ObjectHeader>(); // Seems to always be blank... if (objHeader.ID != 0) Logger.WriteWarning("[OBJ] It seems object {0} has a nonzero objHeader! ({1}) Investigate.", newObj.ObjectName, objHeader.ID); newObj.ZoneName = zone; var thingCount = reader.ReadUInt32(); newObj.ObjectFlags = new byte[thingCount * 4]; for (int i = 0; i < thingCount; i++) { Buffer.BlockCopy(BitConverter.GetBytes(reader.ReadUInt32()), 0, newObj.ObjectFlags, i * 4, 4); // This should work } newObjects.Add(newObj); Logger.WriteInternal("[OBJ] Adding new Object {0} to the database for zone {1}", newObj.ObjectName, zone); } using (var db = new PolarisEf()) { db.GameObjects.AddRange(newObjects); db.SaveChanges(); } }
private void ImportNPCs(string[] args, int length, string full, Client client) { string zone = args[1]; string folder = args[2]; var packetList = Directory.GetFiles(folder); Array.Sort(packetList); List<NPC> newNPCs = new List<NPC>(); foreach (var path in packetList) { var data = File.ReadAllBytes(path); PacketReader reader = new PacketReader(data); PacketHeader header = reader.ReadStruct<PacketHeader>(); if (header.Type != 0x8 || header.Subtype != 0xC) { Logger.WriteWarning("[WRN] File {0} not an NPC spawn packet, skipping.", path); continue; } NPC newNPC = new NPC(); newNPC.EntityID = (int)reader.ReadStruct<ObjectHeader>().ID; var pos = reader.ReadEntityPosition(); newNPC.RotX = pos.RotX; newNPC.RotY = pos.RotY; newNPC.RotZ = pos.RotZ; newNPC.RotW = pos.RotW; newNPC.PosX = pos.PosX; newNPC.PosY = pos.PosY; newNPC.PosZ = pos.PosZ; reader.ReadInt16(); newNPC.NPCName = reader.ReadFixedLengthAscii(0x20); newNPC.ZoneName = zone; newNPCs.Add(newNPC); Logger.WriteInternal("[NPC] Adding new NPC {0} to the database for zone {1}", newNPC.NPCName, zone); } using (var db = new PolarisEf()) { db.NPCs.AddRange(newNPCs); db.SaveChanges(); } }