using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Text; using System.Linq; using System.Data; using SnowLight.Specialized; using SnowLight.Game.Sessions; using SnowLight.Communication; using SnowLight.Game.Characters; using SnowLight.Communication.Outgoing; using SnowLight.Storage; using SnowLight.Game.Pathfinding; using SnowLight.Game.Bots; using SnowLight.Game.Rooms.Events; using SnowLight.Game.Items; using SnowLight.Game.Pets; using SnowLight.Game.Music; using SnowLight.Game.Rooms.Trading; namespace SnowLight.Game.Rooms { public partial class RoomInstance : IDisposable { private uint mInstanceId; private RoomInfo mInfo; private bool mUnloaded; private double mUnloadedTimestamp; private int mMarkedEmptyRoom; public uint InstanceId { get { return mInstanceId; } } public RoomInfo Info { get { return mInfo; } } public uint RoomId { get { return mInfo.Id; } } public bool Unloaded { get { return mUnloaded; } } public double TimeUnloaded { get { return (Unloaded ? UnixTimestamp.GetCurrent() - mUnloadedTimestamp : 0); } } public int MarkedAsEmpty { get { return mMarkedEmptyRoom; } set { mMarkedEmptyRoom = value; } } public List SearchableTags { get { List Tags = new List(); Tags.AddRange(Info.Tags); if (HasOngoingEvent) { Tags.AddRange(Event.Tags); } return Tags; } } public RoomInstance(uint InstanceId, RoomInfo Info, RoomModel Model) { mActorSyncRoot = new object(); mItemSyncRoot = new object(); mInstanceId = InstanceId; mInfo = Info; mActors = new Dictionary(); mCachedModel = Model; mRelativeHeightmap = string.Empty; mActorIdGenerator = 1; mActorIdGeneratorSyncLock = new object(); mTileStates = new TileState[mCachedModel.Heightmap.SizeX, mCachedModel.Heightmap.SizeY]; mUsersWithRights = new List(); mBannedUsers = new Dictionary(); mItems = new Dictionary(); mStaticObjects = new List(); mItemLimitCache = new Dictionary(); mUserGrid = new List[mCachedModel.Heightmap.SizeX, mCachedModel.Heightmap.SizeY]; mMusicController = new RoomMusicController(); mTemporaryStickieRights = new Dictionary(); mTradeManager = new TradeManager(); mRollerItems = new List[mCachedModel.Heightmap.SizeX, mCachedModel.Heightmap.SizeY]; foreach (Bot Bot in BotManager.GenerateBotInstancesForRoom(RoomId)) { AddBotToRoom(Bot); } using (SqlDatabaseClient MySqlClient = SqlDatabaseManager.GetClient()) { // Items MySqlClient.SetParameter("id", RoomId); DataTable ItemTable = MySqlClient.ExecuteQueryTable("SELECT * FROM items WHERE room_id = @id"); foreach (DataRow Row in ItemTable.Rows) { Item Item = ItemFactory.CreateFromDatabaseRow(Row); if (Item.PendingExpiration && Item.ExpireTimeLeft <= 0) { Item.RemovePermanently(MySqlClient); continue; } if (Item.InSoundManager) { continue; } mItems.Add(Item.Id, Item); IncrecementFurniLimitCache(Item.Definition.Behavior); ItemEventDispatcher.InvokeItemEventHandler(null, Item, this, ItemEventType.InstanceLoaded); } // Static objects MySqlClient.SetParameter("id", RoomId); DataTable StaticObjectTable = MySqlClient.ExecuteQueryTable("SELECT name,position,height,rotation,is_seat FROM static_objects WHERE room_id = @id"); foreach (DataRow Row in StaticObjectTable.Rows) { mStaticObjects.Add(new StaticObject((string)Row["name"], Vector2.FromString((string)Row["position"]), (int)Row["height"], (int)Row["rotation"], (Row["is_seat"].ToString() == "1"))); } // Rights MySqlClient.SetParameter("id", RoomId); DataTable RightsTable = MySqlClient.ExecuteQueryTable("SELECT user_id FROM room_rights WHERE room_id = @id"); foreach (DataRow Row in RightsTable.Rows) { mUsersWithRights.Add((uint)Row["user_id"]); } // Pets MySqlClient.SetParameter("id", RoomId); DataTable PetsTable = MySqlClient.ExecuteQueryTable("SELECT * FROM pets WHERE room_id = @id"); foreach (DataRow Row in PetsTable.Rows) { Pet PetData = PetFactory.GetPetFromDatabaseRow(Row); AddBotToRoom(BotManager.CreateNewInstance(BotManager.GetHandlerDefinitionForPetType(PetData.Type), RoomId, Vector3.FromString(Row["room_pos"].ToString()), PetData)); } } RegenerateRelativeHeightmap(); } public static RoomInstance TryCreateRoomInstance(uint InstanceId, uint RoomId) { RoomInfo Info = RoomInfoLoader.GetRoomInfo(RoomId); if (Info == null) { return null; } RoomModel Model = Info.TryGetModel(); if (Model == null) { return null; } return new RoomInstance(InstanceId, Info, Model); } public void Unload() { if (mUnloaded) { return; } mUnloaded = true; if (mActorCountSyncNeeded) { DoActorCountSync(); } BroadcastMessage(RoomKickedComposer.Compose()); lock (mActorSyncRoot) { mActors.Clear(); } mUnloadedTimestamp = UnixTimestamp.GetCurrent(); } public void Dispose() { if (!mUnloaded) { Unload(); } mInfo = null; } } }