/* Thor Server 2.0 Project - Codenamed "Stockholm" Copyright 2008 - 2009 Joe Hegarty This file is part of The Thor Server 2.0 Project - Codenamed "Stockholm". The Thor Server 2.0 Project - Codenamed "Stockholm" is free software: you can redistribute it and/or modify it under the terms of the Microsoft Public License The Thor Server Project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Microsoft Public License for more details. You should have received a copy of the Microsoft Public License along with The Thor Server Project. If not, see http://www.opensource.org/licenses/ms-pl.html */ using System; using System.Collections.Generic; using System.Threading.Tasks; using StockholmLibrary.Game.Flats; using StockholmLibrary.Game.Sessions; using StockholmLibrary.Game.Packets.Client; using StockholmLibrary.Game.Packets.Server; using StockholmLibrary.Net; namespace StockholmLibrary.Game.Entities.Components { //------------------------------------ public class ECCreatureCollection : EntityComponent { public Dictionary CreatureEntities = new Dictionary(); public object CreatureListLock = new object(); Flat _flat; int _creatureCount = 0; //********************************************** public override void FlatInitiailise(Flat flat) { _flat = flat; } //********************************************** public override void FlatDeinitiailise(Flat flat) { } //********************************************** public override void UserInitiailise(Session userSession) { RegisterSessionHandler(userSession, EClientPacket.G_USRS, new PacketRoutingInfo.ProcessPacketDelegate(HandleGetUsers)); RegisterSessionHandler(userSession, EClientPacket.G_STAT, new PacketRoutingInfo.ProcessPacketDelegate(HandleEnterRoom)); } //********************************************** public void SendToCreatureSession(Entity entity, ServerPacket packet) { if (entity != null && packet != null) { ECSession ecSession = null; if (entity.GetEC(ref ecSession)) { ecSession.SendPacket(packet); } } } //********************************************** public void SendToAllCreatureSessions(ServerPacket packet) { if (packet != null) { lock (CreatureListLock) { foreach (var creature in CreatureEntities) { SendToCreatureSession(creature.Value, packet); } } } } //********************************************** public override void UserDeinitiailise(Session userSession) { CleanupSessionHandlers(userSession); lock (CreatureListLock) { if (CreatureEntities.ContainsKey(userSession)) { Entity creature = CreatureEntities[userSession]; ECCreature ecCreature = null; if (creature.GetEC(ref ecCreature)) { ecCreature.SendLeaving(); } CreatureEntities.Remove(userSession); } } } //********************************************** private void HandleGetUsers(ClientPacket packet) { List creatureObjects = new List(); lock (CreatureListLock) { foreach (var creature in CreatureEntities) { ECCreature ecCreature = null; if (creature.Value.GetEC(ref ecCreature)) { creatureObjects.Add(ecCreature.GetCreatureObject()); } } } packet.Peer.EnqueuePacket(new UsersPacket(creatureObjects)); } //********************************************** private void HandleEnterRoom(ClientPacket packet) { Task.Factory.StartNew(() => { Entity creature = CreateCreatureFromSession(packet.Peer.Session); UpdateCreatureStatus(true, creature); ECCreatureStatus status = null; if (creature.GetEC(ref status)) { status.MarkAsDirty(); } } ); } //********************************************** private Entity CreateCreatureFromSession(Session session) { Entity entity = GetParentEntity().AddChild("CreatureUser"); ECCreature creature = entity.AddEC(); ECPhysics physics = entity.AddEC(); creature.Initialise(++_creatureCount); entity.AddEC(); entity.AddEC(); entity.AddEC(); entity.AddEC(); entity.AddEC(); entity.AddEC(); entity.AddEC(); entity.AddEC(); entity.AddEC(); entity.FlatInitialise(_flat); entity.UserInitialise(session); physics.InitialisePhysicsObject(GameConstants.PLAYER_PHYSICS_OBJECT_ID); lock (CreatureListLock) { CreatureEntities.Add(session, entity); } creature.AnnounceCreatureObject(); return entity; } //********************************************** public int GetCreatureIDByECName(string name) { lock (CreatureListLock) { foreach (var creature in CreatureEntities) { ECName ecName = null; if (creature.Value.GetEC(ref ecName)) { if (name == ecName.Name) { ECCreature ecCreature = null; if (creature.Value.GetEC(ref ecCreature)) { return ecCreature.ID; } } } } } return -1; } //********************************************** public Entity GetCreatureByID(int creatureId) { lock (CreatureListLock) { foreach (var creature in CreatureEntities) { ECCreature ecCreature = null; if (creature.Value.GetEC(ref ecCreature)) { if (ecCreature.ID == creatureId) { return creature.Value; } } } } return null; } //********************************************** public override void Pulse() { UpdateCreatureStatus(); } //********************************************** private void UpdateCreatureStatus(bool forceAll = false, Entity sendTo = null) { lock (CreatureListLock) { List statusList = new List(); foreach (var creature in CreatureEntities) { ECCreatureStatus ecCreatureStatus = null; if (creature.Value.GetEC(ref ecCreatureStatus)) { CreatureStatus status = ecCreatureStatus.GetNextStatus(forceAll); if (status != null) { // This means it has changed since last time statusList.Add(status); } } } if (sendTo == null) { if (statusList.Count > 0) { SendToAllCreatureSessions(new StatusPacket(statusList)); } } else { SendToCreatureSession(sendTo, new StatusPacket(statusList)); } } } } }