void Update(Level lvl) { cfg.SaveFor(lvlName); if (lvl == null) { return; } if (isVisit && lvl == Server.mainLevel) { return; } Player[] players = PlayerInfo.Online.Items; foreach (Player p in players) { if (p.level != lvl) { continue; } bool allowed = CheckAllowed(p); if (!isVisit) { p.AllowBuild = allowed; } else if (!allowed) { p.Message("&WNo longer allowed to visit %S{0}", ColoredName); PlayerActions.ChangeMap(p, Server.mainLevel); } } }
public void Goto(string warp, Player p) { Warp wp = Find(warp); if (wp == null) { return; } Level lvl = LevelInfo.FindExact(wp.lvlname); if (p.level != lvl) { PlayerActions.ChangeMap(p, lvl); } if (p.level.name.CaselessEq(wp.lvlname)) { p.SendPos(Entities.SelfID, wp.x, wp.y, wp.z, wp.rotx, wp.roty); Player.Message(p, "Sent you to waypoint/warp"); } else { Player.Message(p, "Unable to send you to the warp as the map it is on is not loaded."); } }
bool SendRawMapCore(Level prev, Level level) { bool success = true; try { if (level.blocks == null) { throw new InvalidOperationException("Tried to join unloaded level"); } useCheckpointSpawn = false; lastCheckpointIndex = -1; AFKCooldown = DateTime.UtcNow.AddSeconds(2); ZoneIn = null; AllowBuild = level.BuildAccess.CheckAllowed(this); SendMapMotd(); Session.SendLevel(prev, level); Loading = false; OnSentMapEvent.Call(this, prev, level); } catch (Exception ex) { success = false; PlayerActions.ChangeMap(this, Server.mainLevel); Message("&WThere was an error sending the map, you have been sent to the main level."); Logger.LogError(ex); } finally { Server.DoGC(); } return(success); }
void UpdateAllowVisit() { if (!IsVisit || lvl == Server.mainLevel) { return; } Player[] players = PlayerInfo.Online.Items; foreach (Player p in players) { if (p.level != lvl) { continue; } LevelAccess access = Check(p); bool allowVisit = access == LevelAccess.Whitelisted || access == LevelAccess.Allowed; if (allowVisit) { continue; } Player.Message(p, "&cNo longer allowed to visit %S{0}", lvl.ColoredName); PlayerActions.ChangeMap(p, Server.mainLevel, false); } }
bool SendRawMapCore(Level oldLevel, Level level) { if (level.blocks == null) { return(false); } bool success = true; useCheckpointSpawn = false; lastCheckpointIndex = -1; AFKCooldown = DateTime.UtcNow.AddSeconds(2); SendMapMotd(); AccessResult access = level.BuildAccess.Check(this); AllowBuild = access == AccessResult.Whitelisted || access == AccessResult.Allowed; try { Send(Packet.LevelInitalise()); if (hasBlockDefs) { if (oldLevel != null && oldLevel != level) { RemoveOldLevelCustomBlocks(oldLevel); } BlockDefinition.SendLevelCustomBlocks(this); if (Supports(CpeExt.InventoryOrder)) { BlockDefinition.SendLevelInventoryOrder(this); } } using (LevelChunkStream s = new LevelChunkStream(this)) LevelChunkStream.CompressMap(this, s); // Force players to read the MOTD (clamped to 3 seconds at most) if (level.Config.LoadDelay > 0) { System.Threading.Thread.Sleep(level.Config.LoadDelay); } byte[] buffer = Packet.LevelFinalise(level.Width, level.Height, level.Length); Send(buffer); Loading = false; OnJoinedLevelEvent.Call(this, oldLevel, level); } catch (Exception ex) { success = false; PlayerActions.ChangeMap(this, Server.mainLevel); SendMessage("There was an error sending the map data, you have been sent to the main level."); Logger.LogError(ex); } finally { Server.DoGC(); } return(success); }
void MovePlayersToMain() { Player[] players = PlayerInfo.Online.Items; foreach (Player p in players) { if (p.level == this) { p.Message("You were moved to the main level as " + ColoredName + " &Swas unloaded."); PlayerActions.ChangeMap(p, Server.mainLevel); } } }
/// <summary> Renames the given map and associated metadata. Does not unload. </summary> /// <remarks> Backups are NOT renamed. </remarks> public static bool Rename(Player p, string src, string dst) { if (LevelInfo.MapExists(dst)) { p.Message("&WLevel \"{0}\" already exists.", dst); return(false); } Level lvl = LevelInfo.FindExact(src); if (lvl == Server.mainLevel) { p.Message("Cannot rename the main level."); return(false); } List <Player> players = null; if (lvl != null) { players = lvl.getPlayers(); } if (lvl != null && !lvl.Unload()) { p.Message("Unable to rename the level, because it could not be unloaded. " + "A game may currently be running on it."); return(false); } File.Move(LevelInfo.MapPath(src), LevelInfo.MapPath(dst)); DoAll(src, dst, action_move); // TODO: Should we move backups still try { //MoveBackups(src, dst); } catch { } RenameDatabaseTables(p, src, dst); BlockDBFile.MoveBackingFile(src, dst); OnLevelRenamedEvent.Call(src, dst); if (players == null) { return(true); } // Move all the old players to the renamed map Load(p, dst, false); foreach (Player pl in players) { PlayerActions.ChangeMap(pl, dst); } return(true); }
public void Goto(Warp warp, Player p) { if (!p.level.name.CaselessEq(warp.Level)) { PlayerActions.ChangeMap(p, warp.Level); } if (p.level.name.CaselessEq(warp.Level)) { p.SendPosition(warp.Pos, new Orientation(warp.Yaw, warp.Pitch)); p.Message("Sent you to waypoint/warp"); } else { p.Message("Unable to send you to the warp as the map it is on is not loaded."); } }
void Goto(Player p, string playerName = null, ushort page = 0) { bool all = false; if (playerName != null) { playerName = playerName.ToLower(); if (playerName == "all") { all = true; } else if (playerName == "public") { playerName = null; } else { playerName = StoredCustomModel.GetPlayerName(playerName) ?? StoredCustomModel.GetPlayerName(playerName + "+"); } } List <string> modelNames; if (all) { var dict = GetAllModels(p); modelNames = dict // public ones first .OrderByDescending(pair => pair.Key == "Public") // then by player name A-Z .ThenBy(pair => pair.Key) .Select(pair => pair.Value) .SelectMany(x => x) .ToList(); } else { modelNames = GetModels(playerName, p); } if (modelNames == null) { return; } // - 1 for our self player var partitionSize = Packet.MaxCustomModels - 1; var partitions = modelNames.Partition(partitionSize).ToList(); if (page >= partitions.Count) { p.Message( "%WPage doesn't exist" ); return; } var total = modelNames.Count; modelNames = partitions[page]; p.Message( "%HViewing %T{0} %Hmodels{1}", total, partitions.Count > 1 ? string.Format( " %S(page %T{0}%S/%T{1}%S)", page + 1, partitions.Count ) : "" ); if (partitions.Count > 1 && page < (partitions.Count - 1)) { p.Message( "%SUse \"%H/cm goto {0} {1}%S\" to go to the next page", playerName, page + 2 ); } var mapName = string.Format( "&f{0} Custom Models{1}", all ? "All" : ( playerName == null ? "Public" : GetNameWithoutPlus(playerName) + "'s" ), page != 0 ? string.Format(" ({0})", page + 1) : "" ); ushort spacing = 4; ushort width = (ushort)( // edges (spacing * 2) + // grass blocks modelNames.Count + // inbetween blocks ((modelNames.Count - 1) * (spacing - 1)) ); ushort height = 1; ushort length = 16; byte[] blocks = new byte[width * height * length]; Level lvl = new Level(mapName, width, height, length, blocks); for (int i = 0; i < blocks.Length; i++) { blocks[i] = 1; } lvl.SaveChanges = false; lvl.ChangedSinceBackup = false; lvl.IsMuseum = true; lvl.BuildAccess.Min = LevelPermission.Nobody; lvl.Config.Physics = 0; lvl.spawnx = spacing; lvl.spawny = 2; lvl.Config.HorizonBlock = 1; lvl.Config.EdgeLevel = 1; lvl.Config.CloudsHeight = -0xFFFFFF; lvl.Config.SidesOffset = 0; lvl.Config.Buildable = false; lvl.Config.Deletable = false; for (ushort i = 0; i < modelNames.Count; i++) { ushort x = (ushort)(spacing + (i * spacing)); ushort y = 0; ushort z = spacing; blocks[lvl.PosToInt(x, y, z)] = 2; var modelName = modelNames[i]; var storedModel = new StoredCustomModel(modelName); if (storedModel.Exists()) { storedModel.LoadFromFile(); } var skinName = p.SkinName; if ( !storedModel.usesHumanSkin && storedModel.defaultSkin != null ) { skinName = storedModel.defaultSkin; } // hack because clients strip + at the end var botName = "&f" + (modelName.EndsWith("+") ? modelName + "&0+" : modelName); var bot = new PlayerBot(botName, lvl) { id = (byte)i, Model = modelName, SkinName = skinName, }; bot.SetInitialPos(Position.FromFeetBlockCoords(x, y + 1, z)); bot.SetYawPitch(Orientation.DegreesToPacked(180), Orientation.DegreesToPacked(0)); bot.ClickedOnText = "/CustomModel wear " + modelName; _ = lvl.Bots.Add(bot); } if (!PlayerActions.ChangeMap(p, lvl)) { return; } }
bool SendRawMapCore(Level prev, Level level) { bool success = true; try { if (level.blocks == null) { throw new InvalidOperationException("Tried to join unloaded level"); } useCheckpointSpawn = false; lastCheckpointIndex = -1; AFKCooldown = DateTime.UtcNow.AddSeconds(2); ZoneIn = null; SendMapMotd(); AllowBuild = level.BuildAccess.CheckAllowed(this); int volume = level.blocks.Length; if (Supports(CpeExt.FastMap)) { Send(Packet.LevelInitaliseExt(volume)); } else { Send(Packet.LevelInitalise()); } if (hasBlockDefs) { if (prev != null && prev != level) { RemoveOldLevelCustomBlocks(prev); } BlockDefinition.SendLevelCustomBlocks(this); if (Supports(CpeExt.InventoryOrder)) { BlockDefinition.SendLevelInventoryOrder(this); } } using (LevelChunkStream dst = new LevelChunkStream(this)) using (Stream stream = LevelChunkStream.CompressMapHeader(this, volume, dst)) { if (level.MightHaveCustomBlocks()) { LevelChunkStream.CompressMap(this, stream, dst); } else { LevelChunkStream.CompressMapSimple(this, stream, dst); } } // Force players to read the MOTD (clamped to 3 seconds at most) if (level.Config.LoadDelay > 0) { System.Threading.Thread.Sleep(level.Config.LoadDelay); } byte[] buffer = Packet.LevelFinalise(level.Width, level.Height, level.Length); Send(buffer); Loading = false; OnSentMapEvent.Call(this, prev, level); } catch (Exception ex) { success = false; PlayerActions.ChangeMap(this, Server.mainLevel); Message("&WThere was an error sending the map, you have been sent to the main level."); Logger.LogError(ex); } finally { Server.DoGC(); } return(success); }
bool SendRawMapCore(Level oldLevel, Level level) { if (level.blocks == null) { return(false); } bool success = true; useCheckpointSpawn = false; lastCheckpointIndex = -1; LevelAccess access = level.BuildAccess.Check(this); AllowBuild = access == LevelAccess.Whitelisted || access == LevelAccess.Allowed; try { if (hasBlockDefs) { if (oldLevel != null && oldLevel != level) { RemoveOldLevelCustomBlocks(oldLevel); } BlockDefinition.SendLevelCustomBlocks(this); } SendRaw(Opcode.LevelInitialise); using (LevelChunkStream s = new LevelChunkStream(this)) LevelChunkStream.CompressMap(this, s); byte[] buffer = new byte[7]; buffer[0] = Opcode.LevelFinalise; NetUtils.WriteI16((short)level.Width, buffer, 1); NetUtils.WriteI16((short)level.Height, buffer, 3); NetUtils.WriteI16((short)level.Length, buffer, 5); Send(buffer); AFKCooldown = DateTime.UtcNow.AddSeconds(2); Loading = false; if (HasCpeExt(CpeExt.EnvWeatherType)) { Send(Packet.EnvWeatherType((byte)level.Weather)); } if (HasCpeExt(CpeExt.EnvColors)) { SendCurrentEnvColors(); } SendCurrentMapAppearance(); if (HasCpeExt(CpeExt.BlockPermissions)) { SendCurrentBlockPermissions(); } if (OnSendMap != null) { OnSendMap(this, buffer); } if (!level.guns && aiming) { aiming = false; ClearBlockchange(); } } catch (Exception ex) { success = false; PlayerActions.ChangeMap(this, Server.mainLevel); SendMessage("There was an error sending the map data, you have been sent to the main level."); Server.ErrorLog(ex); } finally { GC.Collect(); GC.WaitForPendingFinalizers(); } return(success); }
void CompleteLoginProcess() { Player clone = null; OnPlayerFinishConnectingEvent.Call(this); if (cancelconnecting) { cancelconnecting = false; return; } lock (PlayerInfo.Online.locker) { // Check if any players online have same name Player[] players = PlayerInfo.Online.Items; foreach (Player pl in players) { if (pl.truename == truename) { clone = pl; break; } } // Remove clone from list (hold lock for as short time as possible) if (clone != null && Server.Config.VerifyNames) { PlayerInfo.Online.Remove(clone); } id = NextFreeId(); PlayerInfo.Online.Add(this); } if (clone != null && Server.Config.VerifyNames) { string reason = ip == clone.ip ? "(Reconnecting)" : "(Reconnecting from a different IP)"; clone.Leave(reason); } else if (clone != null) { Leave(null, "Already logged in!", true); return; } SendRawMap(null, level); if (Socket.Disconnected) { return; } loggedIn = true; SessionStartTime = DateTime.UtcNow; LastLogin = DateTime.Now; TotalTime = TimeSpan.FromSeconds(1); GetPlayerStats(); ShowWelcome(); Server.Background.QueueOnce(ShowAltsTask, name, TimeSpan.Zero); CheckState(); if (!Directory.Exists("players")) { Directory.CreateDirectory("players"); } PlayerDB.Load(this); Game.Team = Team.TeamIn(this); SetPrefix(); LoadCpeData(); if (Server.Config.verifyadmins && Rank >= Server.Config.VerifyAdminsRank) { adminpen = true; } if (Server.noEmotes.Contains(name)) { parseEmotes = !Server.Config.ParseEmotes; } hideRank = Rank; hidden = CanUse("Hide") && Server.hidden.Contains(name); if (hidden) { Message("&8Reminder: You are still hidden."); } if (Chat.AdminchatPerms.UsableBy(Rank) && Server.Config.AdminsJoinSilently) { hidden = true; adminchat = true; } OnPlayerConnectEvent.Call(this); if (cancellogin) { cancellogin = false; return; } string joinMsg = "&a+ λFULL %S" + PlayerDB.GetLoginMessage(this); if (hidden) { joinMsg = "&8(hidden)" + joinMsg; } if (Server.Config.GuestJoinsNotify || Rank > LevelPermission.Guest) { Chat.MessageFrom(ChatScope.All, this, joinMsg, null, Chat.FilterVisible(this), !hidden); } if (Server.Config.AgreeToRulesOnEntry && Rank == LevelPermission.Guest && !Server.agreed.Contains(name)) { Message("&9You must read the &c/Rules &9and &c/Agree &9to them before you can build and use commands!"); agreed = false; } if (Server.Config.verifyadmins && Rank >= Server.Config.VerifyAdminsRank) { if (!Directory.Exists("extra/passwords") || !File.Exists("extra/passwords/" + name + ".dat")) { Message("%WPlease set your admin verification password with %T/SetPass [password]!"); } else { Message("%WPlease complete admin verification with %T/Pass [password]!"); } } if (CanUse("Inbox") && Database.TableExists("Inbox" + name)) { int count = Database.CountRows("Inbox" + name); if (count > 0) { Message("You have &a" + count + " %Smessages in %T/Inbox"); } } if (Server.Config.PositionUpdateInterval > 1000) { Message("Lowlag mode is currently &aON."); } if (String.IsNullOrEmpty(appName)) { Logger.Log(LogType.UserActivity, "{0} [{1}] connected.", name, ip); } else { Logger.Log(LogType.UserActivity, "{0} [{1}] connected using {2}.", name, ip, appName); } PlayerActions.PostSentMap(this, null, level, false); Loading = false; if (RestoreLastMap.ContainsKey(truename)) { string levelName = RestoreLastMap[truename]; if (Formatter.ValidMapName(this, levelName) && (levelName != Server.mainLevel.name)) { Logger.Log(LogType.UserActivity, "{0} Restoring last map {1}", truename, levelName); PlayerActions.ChangeMap(this, levelName); } } }