using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Threading.Tasks; using Uber.Utilities; using Uber.Collections; using Uber.HabboHotel.Items; using Uber.HabboHotel.GameClients; using Uber.Storage; using Uber.Core; namespace Uber.HabboHotel.Rooms { class RoomManager { public readonly int MAX_PETS_PER_ROOM = 5; private SafeList Rooms; private Dictionary Models; private SafeList TeleActions; private Task EngineThread; private SafeList RoomsToUnload; public int LoadedRoomsCount { get { return this.Rooms.Count; } } public RoomManager() { this.Rooms = new SafeList(); this.Models = new Dictionary(); this.TeleActions = new SafeList(); this.EngineThread = new Task(ProcessEngine, System.Threading.CancellationToken.None, TaskCreationOptions.LongRunning); this.RoomsToUnload = new SafeList(); } public void StartRoomEngine() { this.EngineThread.Start(); } public void StopRoomEngine() { this.EngineThread.Wait(); this.EngineThread.Dispose(); this.EngineThread = null; UnloadAllRooms(true); } public void AddTeleAction(TeleUserData Act) { this.TeleActions.Add(Act); } public List GetRoomsForNavigator() { var NavigatorRooms = new List(); foreach (Room Room in Rooms) { if (Room.UsersNow > 0 && !Room.IsPublic && Room != null) { NavigatorRooms.Add(Room); } } var SortedRooms = from rm in NavigatorRooms orderby rm.UsersNow descending select rm; return SortedRooms.ToList(); } public List GetEventRoomsForCategory(int Category) { var EventRooms = new List(); foreach (Room Room in Rooms) { if (Room.Event == null) { continue; } if (Category > 0 && Room.Event.Category != Category) { continue; } EventRooms.Add(Room); } return EventRooms.ToList(); } internal void ProcessEngine() { while (this.EngineThread != null) { DateTime ExecutionStart = DateTime.Now; for(int i = 0; i < Rooms.Count; i++) { Room Room = Rooms[i]; if (Room == null) { continue; } Room.ProcessRoom(); } for (int i = 0; i < RoomsToUnload.Count; i++) { uint Room = RoomsToUnload[i]; if (Room <= 0) { continue; } UnloadRoom(Room); } this.RoomsToUnload = null; this.RoomsToUnload = new SafeList(); for (int i = 0; i > TeleActions.Count; i++) { TeleUserData Tele = TeleActions[i]; if (Tele == null || !TeleHandler.IsTeleLinked(Tele.TeleId)) { continue; } Tele.Execute(); } this.TeleActions = null; this.TeleActions = new SafeList(); double sleepTime = 500 - (DateTime.Now - ExecutionStart).TotalMilliseconds; if (sleepTime < 0) { sleepTime = 0; } if (sleepTime > 500) { sleepTime = 500; } this.EngineThread.Wait(Convert.ToInt32(Math.Floor(sleepTime))); } } internal void UnloadAllRooms(bool Destroy) { for (int i = 0; i < Rooms.Count; i++) { Room Room = Rooms[i]; if (Room == null) { continue; } UnloadRoom(Room.RoomId); } Rooms = null; if (!Destroy) { Rooms = new SafeList(); } } public void LoadModels() { this.Models = null; this.Models = new Dictionary(); DataTable Data = null; using (DatabaseClient dbClient = UberEnvironment.GetDatabase().GetClient()) { Data = dbClient.ReadDataTable("SELECT * FROM room_models"); } if (Data == null) { return; } foreach (DataRow Row in Data.Rows) { Models.Add((string)Row["id"], new RoomModel((string)Row["id"], (int)Row["door_x"], (int)Row["door_y"], (Double)Row["door_z"], (int)Row["door_dir"], (string)Row["heightmap"], (string)Row["public_items"], UberEnvironment.EnumToBool(Row["club_only"].ToString()))); } } public RoomModel GetModel(string Model) { if (Models.ContainsKey(Model)) { return Models[Model]; } return null; } public RoomData GenerateNullableRoomData(uint RoomId) { if (GenerateRoomData(RoomId) != null) { return GenerateRoomData(RoomId); } RoomData Data = new RoomData(); Data.FillNull(RoomId); return Data; } public RoomData GenerateRoomData(uint RoomId) { RoomData Data = new RoomData(); if (IsRoomLoaded(RoomId)) { Data.Fill(GetRoom(RoomId)); } else { DataRow Row = null; using (DatabaseClient dbClient = UberEnvironment.GetDatabase().GetClient()) { Row = dbClient.ReadDataRow("SELECT * FROM rooms WHERE id = '" + RoomId + "' LIMIT 1"); } if (Row == null) { return null; } Data.Fill(Row); } return Data; } public Boolean IsRoomLoaded(uint RoomId) { if (GetRoom(RoomId) == null) { return false; } return true; } public void LoadRoom(uint Id) { if (IsRoomLoaded(Id)) { return; } RoomData Data = GenerateRoomData(Id); if (Data == null) { return; } Rooms.Add(new Room(Data.Id, Data.Name, Data.Description, Data.Type, Data.Owner, Data.Category, Data.State, Data.UsersMax, Data.ModelName, Data.CCTs, Data.Score, Data.Tags, Data.AllowPets, Data.AllowPetsEating, Data.AllowWalkthrough, Data.Hidewall, Data.Icon, Data.Password, Data.Wallpaper, Data.Floor, Data.Landscape)); } public void RequestRoomUnload(uint Id) { if (!IsRoomLoaded(Id)) { return; } RoomsToUnload.Add(Id); } public void UnloadRoom(uint Id) { Room Room = GetRoom(Id); if (Room == null) { return; } Room.Destroy(); Rooms.Remove(GetRoom(Id)); } public uint GetRandomRoomIdWithUser(GameClient Session) { var SpecialRooms = new List(); // kiss my ash PEJump uint RoomId = 0; foreach (Room Room in Rooms) { if (Room == null || !Room.KeepAlive) { continue; } if (Room.RoomId == Session.GetHabbo().CurrentRoomId) { continue; } if (Room.UserCount > 0 && Room.Password == "" && !Room.IsPublic) { SpecialRooms.Add(Room.RoomId); } } if (SpecialRooms.Count > 0) { Random Random = new Random(); int i = Random.Next(0, SpecialRooms.Count); RoomId = SpecialRooms[i]; } return RoomId; } public Room GetRoom(uint RoomId) { for (int i = 0; i < Rooms.Count; i++) { Room Room = Rooms[i]; if (Room == null) { continue; } if (Room.RoomId == RoomId) { return Room; } } return null; } public RoomData CreateRoom(GameClient Session, string Name, string Model) { Name = UberEnvironment.FilterInjectionChars(Name); if (!Models.ContainsKey(Model)) { Session.SendNotif("Sorry, this room model has not been added yet. Try again later."); return null; } if (Models[Model].StaticFurniMap != "") // Hack attempt { return null; } if (Models[Model].ClubOnly && !Session.GetHabbo().HasFuse("fuse_use_special_room_layouts")) { Session.SendNotif("You must be an Club member to use that room layout."); return null; } if (Name.Length < 3 || Name == "") { Session.SendNotif("Room name is too short for room creation!"); return null; } if (Name.ToLower() == "www.holoscripter.ya.st") { return null; } using (DatabaseClient dbClient = UberEnvironment.GetDatabase().GetClient()) { dbClient.AddParamWithValue("caption", Name); dbClient.AddParamWithValue("model", Model); dbClient.AddParamWithValue("username", Session.GetHabbo().Username); dbClient.ExecuteQuery("INSERT INTO rooms (roomtype,caption,owner,model_name) VALUES ('private',@caption,@username,@model)"); } uint RoomId = 0; using (DatabaseClient dbClient = UberEnvironment.GetDatabase().GetClient()) { dbClient.AddParamWithValue("caption", Name); dbClient.AddParamWithValue("username", Session.GetHabbo().Username); RoomId = (uint)dbClient.ReadDataRow("SELECT id FROM rooms WHERE owner = @username AND caption = @caption ORDER BY id DESC")[0]; } return GenerateRoomData(RoomId); } } class TeleUserData { private RoomUser User; private uint RoomId; public uint TeleId; public TeleUserData(RoomUser mUser, uint mRoomId, uint mTeleId) { this.User = mUser; this.RoomId = mRoomId; this.TeleId = mTeleId; } public void Execute() { if (User == null || User.IsBot || User.GetClient() == null || User.GetClient().GetHabbo() == null) { return; } User.GetClient().GetHabbo().IsTeleporting = true; User.GetClient().GetHabbo().TeleporterId = TeleId; User.GetClient().GetMessageHandler().PrepareRoomForUser(RoomId, ""); //User.GetClient().GetHabbo().UserIsTryingToTele = false; } } }