diff --git a/Commands/CmdOverseer.cs b/Commands/CmdOverseer.cs index a53611386..dc2506a0f 100644 --- a/Commands/CmdOverseer.cs +++ b/Commands/CmdOverseer.cs @@ -80,7 +80,7 @@ namespace MCGalaxy.Commands { Player[] players = PlayerInfo.Online.Items; foreach (Player pl in players) { if (pl.level == p.level && pl.name != p.name) - PlayerActions.ChangeMap(pl, Server.mainLevel.name); + PlayerActions.ChangeMap(pl, Server.mainLevel); } } else if (cmd == "KICK") { if (arg == "") { p.SendMessage("You must specify a player to kick."); return; } @@ -88,7 +88,7 @@ namespace MCGalaxy.Commands { Player pl = PlayerInfo.FindMatches(p, arg); if (pl != null) { if (pl.level.name == p.level.name) - PlayerActions.ChangeMap(pl, Server.mainLevel.name); + PlayerActions.ChangeMap(pl, Server.mainLevel); else p.SendMessage("Player is not on your level!"); } @@ -257,7 +257,7 @@ namespace MCGalaxy.Commands { } Player.Message(p, blocked.name + " has been blacklisted from your map."); if (blocked.level.name == p.level.name) { - PlayerActions.ChangeMap(blocked, Server.mainLevel.name); return; + PlayerActions.ChangeMap(blocked, Server.mainLevel); return; } } else if (cmd == "UNBLOCK") { if (value == "") { diff --git a/Commands/Information/CmdMapInfo.cs b/Commands/Information/CmdMapInfo.cs index 66bf13003..ca905bb7a 100644 --- a/Commands/Information/CmdMapInfo.cs +++ b/Commands/Information/CmdMapInfo.cs @@ -74,10 +74,12 @@ namespace MCGalaxy.Commands { } Player.Message(p, " BlockDB (Used for /b) is {0}", data.blockDB ? "&aEnabled" : "&cDisabled"); ShowPermissions(p, data); - Player.Message(p, "Use %T/mi env {0} %Sto see environment settings.", data.Name); + Player.Message(p, "Use %T/mi env {0} %Sto see environment settings.", data.Name); + if (!Server.zombie.IsZombieMap(data.Name)) return; - if (!Server.zombie.IsZombieMap(data.Name)) return; - Player.Message(p, "Map authors: " + data.Authors); + string[] authors = data.Authors.Replace(" ", "").Split(','); + Player.Message(p, "Map authors: {0}", + authors.Join(n => PlayerInfo.GetColoredName(p, n))); int winChance = data.TotalRounds == 0 ? 100 : (data.HumanRounds * 100) / data.TotalRounds; Player.Message(p, "&a{0} %Srounds played total, &a{1}% %Swin chance for humans.", data.TotalRounds, winChance); diff --git a/Commands/Moderation/CmdXJail.cs b/Commands/Moderation/CmdXJail.cs index 95d6c8786..897deecb2 100644 --- a/Commands/Moderation/CmdXJail.cs +++ b/Commands/Moderation/CmdXJail.cs @@ -65,7 +65,7 @@ namespace MCGalaxy.Commands { if (who.muted) mute.Use(p, message); if (who.frozen) freeze.Use(p, message); - PlayerActions.ChangeMap(who, Server.mainLevel.name); + PlayerActions.ChangeMap(who, Server.mainLevel); who.BlockUntilLoad(10); jail.Use(p, message); diff --git a/Commands/World/CmdGoto.cs b/Commands/World/CmdGoto.cs index 99470d0a6..9f503dab8 100644 --- a/Commands/World/CmdGoto.cs +++ b/Commands/World/CmdGoto.cs @@ -16,9 +16,6 @@ permissions and limitations under the Licenses. */ using System; -using System.Collections.Generic; -using System.IO; -using MCGalaxy.Games; namespace MCGalaxy.Commands.World { public sealed class CmdGoto : Command { @@ -34,113 +31,13 @@ namespace MCGalaxy.Commands.World { public override void Use(Player p, string message) { if (p == null) { MessageInGameOnly(p); return; } - if (message == "") { Help(p); return; } - if (p.usingGoto) { Player.Message(p, "Cannot use /goto, already loading a map."); return; } - - Level oldLevel = p.level; - p.usingGoto = true; - bool didJoin = false; - try { - didJoin = HandleGoto(p, message); - } finally { - p.usingGoto = false; - GC.Collect(); - GC.WaitForPendingFinalizers(); - } - - if (!didJoin) return; - bool unloadOld = true; - if (oldLevel.unload && !oldLevel.IsMuseum) { - Player[] players = PlayerInfo.Online.Items; - foreach (Player pl in players) - if (pl.level == oldLevel) { unloadOld = false; break; } - if (unloadOld && Server.AutoLoad) oldLevel.Unload(true); - } - } - - bool HandleGoto(Player p, string message) { - Level lvl = LevelInfo.FindExact(message); - if (lvl != null) { - return GoToLevel(p, lvl, message); - } else if (Server.AutoLoad) { - // First try exactly matching unloaded levels - if (LevelInfo.ExistsOffline(message)) - return GotoOfflineLevel(p, message); - lvl = LevelInfo.Find(message); - if (lvl != null) return GoToLevel(p, lvl, message); - - string map = LevelInfo.FindMapMatches(p, message); - if (map == null) return false; - return GotoOfflineLevel(p, map); - } else { - lvl = LevelInfo.Find(message); - if (lvl == null) { - Player.Message(p, "There is no level \"{0}\" loaded. Did you mean..", message); - Command.all.Find("search").Use(p, "levels " + message); - return false; - } - return GoToLevel(p, lvl, message); - } - } - - static bool GotoOfflineLevel(Player p, string message) { - if (Level.CheckLoadOnGoto(message)) { - CmdLoad.LoadLevel(p, message, "0", true); - Level lvl = LevelInfo.Find(message); - if (lvl != null) { - return GoToLevel(p, lvl, message); - } else { - Player.Message(p, "Level \"{0}\" failed to be auto-loaded.", message); - return false; - } - } - Player.Message(p, "Level \"{0}\" cannot be loaded using /goto.", message); - return false; - } - - static bool GoToLevel(Player p, Level lvl, string message) { - if (p.level == lvl) { Player.Message(p, "You are already in \"" + lvl.name + "\"."); return false; } - if (!lvl.CanJoin(p)) return false; - if (!Server.zombie.PlayerCanJoinLevel(p, lvl, p.level)) return false; - - p.Loading = true; - Entities.DespawnEntities(p); - Level oldLevel = p.level; - p.level = lvl; p.SendUserMOTD(); p.SendMap(oldLevel); - - ushort x = (ushort)(lvl.spawnx * 32 + 16); - ushort y = (ushort)(lvl.spawny * 32 + 32); - ushort z = (ushort)(lvl.spawnz * 32 + 16); - Entities.SpawnEntities(p, x, y, z, lvl.rotx, lvl.roty); - p.Loading = false; - CheckGamesJoin(p, oldLevel); - p.prevMsg = ""; - - if (!p.hidden && p.level.ShouldShowJoinMessage(oldLevel)) { - Player.SendChatFrom(p, p.color + "*" + p.DisplayName + " %Swent to &b" + lvl.name, false); - Player.RaisePlayerAction(p, PlayerAction.JoinWorld, lvl.name); - } - return true; - } - - internal static void CheckGamesJoin(Player p, Level oldLvl) { - Server.lava.PlayerJoinedLevel(p, p.level, oldLvl); - Server.zombie.PlayerJoinedLevel(p, p.level, oldLvl); - - if (p.inTNTwarsMap) p.canBuild = true; - TntWarsGame game = TntWarsGame.Find(p.level); - if (game == null) return; - - if (game.GameStatus != TntWarsGame.TntWarsGameStatus.Finished && - game.GameStatus != TntWarsGame.TntWarsGameStatus.WaitingForPlayers) { - p.canBuild = false; - Player.Message(p, "TNT Wars: Disabled your building because you are in a TNT Wars map!"); - } - p.inTNTwarsMap = true; + if (message == "") { Help(p); return; } + if (!Formatter.ValidName(p, message, "level")) return; + PlayerActions.ChangeMap(p, message); } public override void Help(Player p) { - Player.Message(p, "%T/goto "); + Player.Message(p, "%T/goto [map name]"); Player.Message(p, "%HTeleports yourself to a different level."); } } diff --git a/Commands/World/CmdLockdown.cs b/Commands/World/CmdLockdown.cs index afe6bd7c8..b41d47742 100644 --- a/Commands/World/CmdLockdown.cs +++ b/Commands/World/CmdLockdown.cs @@ -61,7 +61,7 @@ namespace MCGalaxy.Commands { } if (p != null && who.level != p.level) { Player.Message(p, "Moving player to your map..."); - PlayerActions.ChangeMap(who, p.level.name); + PlayerActions.ChangeMap(who, p.level); who.BlockUntilLoad(500); } Chat.MessageAll("{0} %Shas been locked down!", who.ColoredName); diff --git a/Commands/World/CmdMain.cs b/Commands/World/CmdMain.cs index bc073adc4..f3e60b5b3 100644 --- a/Commands/World/CmdMain.cs +++ b/Commands/World/CmdMain.cs @@ -33,7 +33,7 @@ namespace MCGalaxy.Commands.World { if (p.level.name == Server.mainLevel.name) { Player.Message(p, "You are already on the server's main level."); return; } - PlayerActions.ChangeMap(p, Server.mainLevel.name); + PlayerActions.ChangeMap(p, Server.mainLevel); } else { if (!CheckExtraPerm(p)) { MessageNeedExtra(p, "change the main level"); return; } if (!Formatter.ValidName(p, message, "level")) return; diff --git a/Commands/World/CmdMuseum.cs b/Commands/World/CmdMuseum.cs index 5a3662249..cd9b6e9ed 100644 --- a/Commands/World/CmdMuseum.cs +++ b/Commands/World/CmdMuseum.cs @@ -74,7 +74,7 @@ namespace MCGalaxy.Commands.World { } public override void Help(Player p) { - Player.Message(p, "%T/museum "); + Player.Message(p, "%T/museum [map] [restore]"); Player.Message(p, "%HAllows you to access a restore of the map entered. Works on unloaded maps"); } } diff --git a/Commands/other/CmdSummon.cs b/Commands/other/CmdSummon.cs index 7f2bbafbc..30a4e5b80 100644 --- a/Commands/other/CmdSummon.cs +++ b/Commands/other/CmdSummon.cs @@ -54,7 +54,7 @@ namespace MCGalaxy.Commands { if (p.level != who.level) { Player.Message(p, who.ColoredName + " %Sis in a different Level. Forcefetching has started!"); - PlayerActions.ChangeMap(who, p.level.name); + PlayerActions.ChangeMap(who, p.level); Thread.Sleep(1000); // Sleep for a bit while they load } diff --git a/Commands/other/CmdTpA.cs b/Commands/other/CmdTpA.cs index 448e5b94c..9d85e833f 100644 --- a/Commands/other/CmdTpA.cs +++ b/Commands/other/CmdTpA.cs @@ -85,8 +85,7 @@ namespace MCGalaxy.Commands { sender.currentTpa = ""; Thread.Sleep(1000); if (p.level != sender.level) { - Level where = p.level; - PlayerActions.ChangeMap(sender, where.name); + PlayerActions.ChangeMap(sender, p.level); Thread.Sleep(1000); } diff --git a/Games/LavaSurvival/LavaSurvival.cs b/Games/LavaSurvival/LavaSurvival.cs index a7d89b6b7..99c2b22d3 100644 --- a/Games/LavaSurvival/LavaSurvival.cs +++ b/Games/LavaSurvival/LavaSurvival.cs @@ -297,9 +297,9 @@ namespace MCGalaxy.Games if (pl.level == oldMap) { if (sendAfkMain && pl.IsAfk) - PlayerActions.ChangeMap(pl, Server.mainLevel.name); + PlayerActions.ChangeMap(pl, Server.mainLevel); else - PlayerActions.ChangeMap(pl, map.name); + PlayerActions.ChangeMap(pl, map); } } if (OnMapChange != null) diff --git a/Games/TntWars/TntWars.cs b/Games/TntWars/TntWars.cs index 1e058ef13..22d77325f 100644 --- a/Games/TntWars/TntWars.cs +++ b/Games/TntWars/TntWars.cs @@ -157,7 +157,7 @@ namespace MCGalaxy.Games { foreach (player p in Players.Where(p => p.p.level != lvl)) { - PlayerActions.ChangeMap(p.p, lvl.name); + PlayerActions.ChangeMap(p.p, lvl); p.p.inTNTwarsMap = true; } if (GameMode == TntWarsGameMode.TDM) { Command.all.Find("reveal").Use(null, "all " + lvl.name); }//So peoples names apear above their heads in the right color! diff --git a/Games/ZombieSurvival/ZombieGame.Game.cs b/Games/ZombieSurvival/ZombieGame.Game.cs index 004a5284b..5ffe54e0b 100644 --- a/Games/ZombieSurvival/ZombieGame.Game.cs +++ b/Games/ZombieSurvival/ZombieGame.Game.cs @@ -83,10 +83,14 @@ namespace MCGalaxy.Games { if (Server.votingforlevel && HandleVote(p, message)) return true; if (message[0] == '~' && message.Length > 1) { - Player[] players = p.Game.Infected ? Infected.Items : Alive.Items; + Player[] players = PlayerInfo.Online.Items; string type = p.Game.Infected ? " &cto zombies%S: " : " &ato humans%S: "; - foreach (Player pl in players) - pl.SendMessage(p.ColoredName + type + message.Substring(1)); + + foreach (Player pl in players) { + if (!pl.level.name.CaselessEq(CurLevelName)) continue; + if (pl.Game.Referee || pl.Game.Infected == p.Game.Infected) + pl.SendMessage(p.ColoredName + type + message.Substring(1)); + } return true; } else if (message[0] == '`' && message.Length > 1) { if (p.Game.Team == null) { @@ -142,8 +146,11 @@ namespace MCGalaxy.Games { "%SPillaring " + (CurLevel.Pillaring ? "&aYes" : "&cNo") + "%S, Type is &a" + CurLevel.BuildType); - if (CurLevel.Authors != "") - p.SendMessage("It was created by " + CurLevel.Authors); + if (CurLevel.Authors != "") { + string[] authors = CurLevel.Authors.Replace(" ", "").Split(','); + Player.Message(p, "It was created by {0}", + authors.Join(n => PlayerInfo.GetColoredName(p, n))); + } PlayerMoneyChanged(p); UpdatePlayerStatus(p); diff --git a/Levels/Level.Blocks.cs b/Levels/Level.Blocks.cs index 364a6c3f4..7968a8996 100644 --- a/Levels/Level.Blocks.cs +++ b/Levels/Level.Blocks.cs @@ -230,9 +230,11 @@ namespace MCGalaxy { BuildAccess.CheckDetailed(p, false); p.ZoneSpam = DateTime.UtcNow.AddSeconds(2); } - - return p.level == this - ? p.AllowBuild : BuildAccess.Check(p, false); + if (p.level == this) return p.AllowBuild; + + LevelAccessResult access = BuildAccess.Check(p, false); + return access == LevelAccessResult.Whitelisted + || access == LevelAccessResult.Allowed; } public bool CheckAffectPermissions(Player p, ushort x, ushort y, ushort z, diff --git a/Levels/Level.cs b/Levels/Level.cs index f4b9c482d..10c6124fc 100644 --- a/Levels/Level.cs +++ b/Levels/Level.cs @@ -208,7 +208,7 @@ namespace MCGalaxy { foreach (Player p in players) { if (p.level == this) { Player.Message(p, "You were moved to the main level as " + name + " was unloaded."); - PlayerActions.ChangeMap(p, Server.mainLevel.name); + PlayerActions.ChangeMap(p, Server.mainLevel); } } } diff --git a/Levels/LevelAccess.cs b/Levels/LevelAccess.cs index 9408c0ec8..77caa1dd9 100644 --- a/Levels/LevelAccess.cs +++ b/Levels/LevelAccess.cs @@ -62,15 +62,21 @@ namespace MCGalaxy { } - /// Returns whether the given player is allowed by these access permissions. - public bool Check(Player p, bool ignoreRankPerm = false) { - if (Blacklisted.CaselessContains(p.name)) return false; - if (Whitelisted.CaselessContains(p.name) || ignoreRankPerm) return true; + /// Returns the allowed state for the given player. + public LevelAccessResult Check(Player p, bool ignoreRankPerm = false) { + if (Blacklisted.CaselessContains(p.name)) + return LevelAccessResult.Blacklisted; + if (Whitelisted.CaselessContains(p.name)) + return LevelAccessResult.Whitelisted; + if (ignoreRankPerm) + return LevelAccessResult.Allowed; - if (p.Rank < Min) return false; + if (p.Rank < Min) + return LevelAccessResult.BelowMinRank; string maxCmd = IsVisit ? "pervisitmax" : "perbuildmax"; - if (p.Rank > Max && !p.group.CanExecute(maxCmd)) return false; - return true; + if (p.Rank > Max && !p.group.CanExecute(maxCmd)) + return LevelAccessResult.AboveMaxRank; + return LevelAccessResult.Allowed; } /// Returns whether the given player is allowed for these access permissions. @@ -134,7 +140,7 @@ namespace MCGalaxy { bool CheckRank(Player p, LevelPermission perm, string target, bool newPerm) { if (p != null && perm > p.Rank) { Player.Message(p, "You cannot change the {0} of a level {1} a {0} higher than your rank.", - target, newPerm ? "to" : "with"); + target, newPerm ? "to" : "with"); return false; } return true; @@ -153,8 +159,29 @@ namespace MCGalaxy { Player[] players = PlayerInfo.Online.Items; foreach (Player p in players) { if (p.level != lvl) continue; - p.AllowBuild = lvl.BuildAccess.Check(p, false); + + LevelAccessResult access = lvl.BuildAccess.Check(p, false); + p.AllowBuild = access == LevelAccessResult.Whitelisted + || access == LevelAccessResult.Allowed; } } } + + public enum LevelAccessResult { + + /// The player is whitelisted and always allowed. + Whitelisted, + + /// The player is blacklisted and never allowed. + Blacklisted, + + /// The player is allowed (by their rank) + Allowed, + + /// The player's rank is below the minimum rank allowed. + BelowMinRank, + + /// The player's rank is above the maximum rank allowed. + AboveMaxRank, + } } \ No newline at end of file diff --git a/Network/Player.Networking.cs b/Network/Player.Networking.cs index 9dbf04381..4749fc4b0 100644 --- a/Network/Player.Networking.cs +++ b/Network/Player.Networking.cs @@ -319,7 +319,10 @@ namespace MCGalaxy { bool success = true; useCheckpointSpawn = false; lastCheckpointIndex = -1; - AllowBuild = level.BuildAccess.Check(this, false); + + LevelAccessResult access = level.BuildAccess.Check(this, false); + AllowBuild = access == LevelAccessResult.Whitelisted + || access == LevelAccessResult.Allowed; try { if (hasBlockDefs) { @@ -356,7 +359,7 @@ namespace MCGalaxy { } } catch (Exception ex) { success = false; - PlayerActions.ChangeMap(this, Server.mainLevel.name); + 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 { diff --git a/Player/Player.Handlers.cs b/Player/Player.Handlers.cs index a2074e23a..6a65e89b1 100644 --- a/Player/Player.Handlers.cs +++ b/Player/Player.Handlers.cs @@ -187,8 +187,8 @@ namespace MCGalaxy { byte[] remaining = new byte[buffer.Length - size]; Buffer.BlockCopy(buffer, size, remaining, 0, remaining.Length); return ProcessReceived(remaining); - } catch (Exception e) { - Server.ErrorLog(e); + } catch (Exception ex) { + Server.ErrorLog(ex); } return buffer; } @@ -441,7 +441,6 @@ return; } void HandleChat(byte[] packet) { - try { if (!loggedIn) return; byte continued = packet[1]; string text = GetString(packet, 2); @@ -518,8 +517,6 @@ return; } } CheckForMessageSpam(); - } - catch ( Exception e ) { Server.ErrorLog(e); Chat.MessageAll("An error occurred: {0}", e.Message); } } bool FilterChat(ref string text, byte continued) { diff --git a/Player/Player.Login.cs b/Player/Player.Login.cs index efc1c01ad..a9ae5ab09 100644 --- a/Player/Player.Login.cs +++ b/Player/Player.Login.cs @@ -20,14 +20,14 @@ using MCGalaxy.Commands.World; using MCGalaxy.Games; using MCGalaxy.SQL; -namespace MCGalaxy { +namespace MCGalaxy { public sealed partial class Player : IDisposable { - + void HandleLogin(byte[] packet) { LastAction = DateTime.UtcNow; - try { - if (loggedIn) return; + if (loggedIn) return; +<<<<<<< HEAD byte version = packet[1]; name = enc.GetString(packet, 2, 64).Trim(); if (name.Length > 16) { @@ -47,89 +47,116 @@ namespace MCGalaxy { } if (altsCount > 0) { Leave("Already logged in!", true); return; +======= + byte version = packet[1]; + name = enc.GetString(packet, 2, 64).Trim(); + if (name.Length > 16) { + Leave("Usernames must be 16 characters or less", true); return; + } + truename = name; + skinName = name; + + int altsCount = 0; + lock (pendingLock) { + DateTime now = DateTime.UtcNow; + foreach (PendingItem item in pendingNames) { + if (item.Name == truename && (now - item.Connected).TotalSeconds <= 60) + altsCount++; +>>>>>>> 22ce3355275dac2590aae6a9ecc600706f28e377 } + pendingNames.Add(new PendingItem(name)); + } + if (altsCount > 0) { + Leave("Already logged in!", true); return; + } - string verify = enc.GetString(packet, 66, 32).Trim(); - verifiedName = false; - if (Server.verify) { - byte[] hash = null; - lock (md5Lock) - hash = md5.ComputeHash(enc.GetBytes(Server.salt + truename)); - - string hashHex = BitConverter.ToString(hash); - if (!verify.CaselessEq(hashHex.Replace("-", ""))) { - if (!IPInPrivateRange(ip)) { - Leave("Login failed! Try signing in again.", true); return; - } - } else { - verifiedName = true; - } - } + string verify = enc.GetString(packet, 66, 32).Trim(); + verifiedName = false; + if (Server.verify) { + byte[] hash = null; + lock (md5Lock) + hash = md5.ComputeHash(enc.GetBytes(Server.salt + truename)); - DisplayName = name; - if (Server.ClassicubeAccountPlus) name += "+"; - isDev = Server.Devs.CaselessContains(truename); - isMod = Server.Mods.CaselessContains(truename); + string hashHex = BitConverter.ToString(hash); + if (!verify.CaselessEq(hashHex.Replace("-", ""))) { + if (!IPInPrivateRange(ip)) { + Leave("Login failed! Try signing in again.", true); return; + } + } else { + verifiedName = true; + } + } + + DisplayName = name; + if (Server.ClassicubeAccountPlus) name += "+"; + isDev = Server.Devs.CaselessContains(truename); + isMod = Server.Mods.CaselessContains(truename); - try { - Server.TempBan tBan = Server.tempBans.Find(tB => tB.name.ToLower() == name.ToLower()); - if (tBan.expiryTime < DateTime.UtcNow) { - Server.tempBans.Remove(tBan); - } else { - string reason = String.IsNullOrEmpty(tBan.reason) ? "" : - " (" + tBan.reason + ")"; - Kick("You're still temp banned!" + reason, true); - } - } catch { } + try { + Server.TempBan tBan = Server.tempBans.Find(tB => tB.name.ToLower() == name.ToLower()); + if (tBan.expiryTime < DateTime.UtcNow) { + Server.tempBans.Remove(tBan); + } else { + string reason = String.IsNullOrEmpty(tBan.reason) ? "" : + " (" + tBan.reason + ")"; + Kick("You're still temp banned!" + reason, true); + } + } catch { } - if (!CheckWhitelist()) { Leave("This is a private server!", true); return; } - Group foundGrp = Group.findPlayerGroup(name); - - // ban check - if (Server.bannedIP.Contains(ip) && (!Server.useWhitelist || !onWhitelist)) { - Kick(Server.defaultBanMessage, true); return; - } - - if (foundGrp.Permission == LevelPermission.Banned) { - string[] data = Ban.GetBanData(name); - if (data != null) { - Kick(Ban.FormatBan(data[0], data[1]), true); - } else { - Kick(Server.defaultBanMessage, true); - } - return; - } - - // maxplayer check - if (!CheckPlayersCount(foundGrp)) return; - if (version != Server.version) { Leave("Wrong version!", true); return; } - - Player[] players = PlayerInfo.Online.Items; - foreach (Player p in players) { - if (p.name != name) continue; - - if (Server.verify) { - string reason = p.ip == ip ? "(Reconnecting)" : "(Reconnecting from a different IP)"; - p.Leave(reason); break; - } else { - Leave("Already logged in!", true); return; - } + if (!CheckWhitelist()) { Leave("This is a private server!", true); return; } + Group foundGrp = Group.findPlayerGroup(name); + + // ban check + if (Server.bannedIP.Contains(ip) && (!Server.useWhitelist || !onWhitelist)) { + Kick(Server.defaultBanMessage, true); return; + } + + if (foundGrp.Permission == LevelPermission.Banned) { + string[] data = Ban.GetBanData(name); + if (data != null) { + Kick(Ban.FormatBan(data[0], data[1]), true); + } else { + Kick(Server.defaultBanMessage, true); } +<<<<<<< HEAD byte type = packet[130]; if (type == 0x42) { hasCpe = true; SendCpeExtensions(); } - - group = foundGrp; - Loading = true; - if (disconnected) return; - id = NextFreeId(); - - if (type != 0x42) - CompleteLoginProcess(); - } catch (Exception e) { - Server.ErrorLog(e); - Chat.MessageAll("An error occurred: {0}", e.Message); +======= + return; } +>>>>>>> 22ce3355275dac2590aae6a9ecc600706f28e377 + + // maxplayer check + if (!CheckPlayersCount(foundGrp)) return; + if (version != Server.version) { Leave("Wrong version!", true); return; } + + Player[] players = PlayerInfo.Online.Items; + foreach (Player p in players) { + if (p.name != name) continue; + + if (Server.verify) { + string reason = p.ip == ip ? "(Reconnecting)" : "(Reconnecting from a different IP)"; + p.Leave(reason); break; + } else { + Leave("Already logged in!", true); return; + } + } + + LoadIgnores(); + byte type = packet[130]; + if (type == 0x42) { hasCpe = true; SendCpeExtensions(); } + + try { left.Remove(name.ToLower()); } + catch { } + + group = foundGrp; + Loading = true; + if (disconnected) return; + id = NextFreeId(); + + if (type != 0x42) + CompleteLoginProcess(); } bool CheckPlayersCount(Group foundGrp) { @@ -194,20 +221,15 @@ namespace MCGalaxy { void CompleteLoginProcess() { LevelPermission adminChatRank = CommandOtherPerms.FindPerm("adminchat", LevelPermission.Admin); - try { - SendUserMOTD(); - SendMap(null); - if (disconnected) return; - loggedIn = true; - - PlayerInfo.Online.Add(this); - connections.Remove(this); - RemoveFromPending(); - Server.s.PlayerListUpdate(); - } catch (Exception e) { - Server.ErrorLog(e); - Chat.MessageAll("An error occurred: {0}", e.Message); - } + SendUserMOTD(); + SendMap(null); + if (disconnected) return; + loggedIn = true; + + PlayerInfo.Online.Add(this); + connections.Remove(this); + RemoveFromPending(); + Server.s.PlayerListUpdate(); //OpenClassic Client Check SendBlockchange(0, 0, 0, 0); @@ -275,17 +297,15 @@ namespace MCGalaxy { Server.s.Log(name + " [" + ip + "] has joined the server."); Game.InfectMessages = PlayerDB.GetInfectMessages(this); Server.zombie.PlayerJoinedServer(this); - try { - ushort x = (ushort)((0.5 + level.spawnx) * 32); - ushort y = (ushort)((1 + level.spawny) * 32); - ushort z = (ushort)((0.5 + level.spawnz) * 32); - pos = new ushort[3] { x, y, z }; rot = new byte[2] { level.rotx, level.roty }; - Entities.SpawnEntities(this, x, y, z, rot[0], rot[1]); - } catch (Exception e) { - Server.ErrorLog(e); - Server.s.Log("Error spawning player \"" + name + "\""); - } - CmdGoto.CheckGamesJoin(this, null); + + ushort x = (ushort)((0.5 + level.spawnx) * 32); + ushort y = (ushort)((1 + level.spawny) * 32); + ushort z = (ushort)((0.5 + level.spawnz) * 32); + pos = new ushort[3] { x, y, z }; + rot = new byte[2] { level.rotx, level.roty }; + + Entities.SpawnEntities(this, x, y, z, rot[0], rot[1]); + PlayerActions.CheckGamesJoin(this, null); Loading = false; } @@ -340,6 +360,7 @@ namespace MCGalaxy { } if (alts.Count == 0) return; +<<<<<<< HEAD LevelPermission adminChatRank = CommandOtherPerms.FindPerm("adminchat", LevelPermission.Admin); string altsMsg = p.ColoredName + " %Sis lately known as: " + alts.Join(); if (p.group.Permission < adminChatRank || !Server.adminsjoinsilent) { @@ -347,6 +368,13 @@ namespace MCGalaxy { //IRCBot.Say(temp, true); //Tells people in op channel on IRC } Server.s.Log(altsMsg); +======= + short reachDist; + if (!short.TryParse(reach, out reachDist)) return; + ReachDistance = reachDist / 32f; + if (HasCpeExt(CpeExt.ClickDistance)) + Send(Packet.MakeClickDistance(reachDist)); +>>>>>>> 22ce3355275dac2590aae6a9ecc600706f28e377 } } } diff --git a/Player/PlayerActions.cs b/Player/PlayerActions.cs index 84a88f7a0..2a9d48421 100644 --- a/Player/PlayerActions.cs +++ b/Player/PlayerActions.cs @@ -14,8 +14,11 @@ BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Licenses for the specific language governing permissions and limitations under the Licenses. -*/ + */ using System; +using MCGalaxy.Games; +using MCGalaxy.Commands.World; + namespace MCGalaxy { public static class PlayerActions { @@ -25,7 +28,7 @@ namespace MCGalaxy { } /// Moves the player to the specified block coordinates. - public static void MoveCoords(Player p, int bX, int bY, int bZ, + public static void MoveCoords(Player p, int bX, int bY, int bZ, byte rotX, byte rotY) { ushort x = (ushort)(bX * 32 + 16); ushort y = (ushort)(bY * 32); @@ -34,8 +37,121 @@ namespace MCGalaxy { } /// Moves the player to the specified map. - public static void ChangeMap(Player p, string name) { - Command.all.Find("goto").Use(p, name); + public static bool ChangeMap(Player p, string name) { return ChangeMap(p, null, name); } + + /// Moves the player to the specified map. + public static bool ChangeMap(Player p, Level lvl) { return ChangeMap(p, lvl, null); } + + static bool ChangeMap(Player p, Level lvl, string name) { + if (p.usingGoto) { Player.Message(p, "Cannot use /goto, already loading a map."); return false; } + Level oldLevel = p.level; + p.usingGoto = true; + bool didJoin = false; + + try { + didJoin = name == null ? + GotoLevel(p, lvl) : GotoMap(p, name); + } finally { + p.usingGoto = false; + GC.Collect(); + GC.WaitForPendingFinalizers(); + } + + if (!didJoin) return false; + Unload(oldLevel); + return true; + } + + + static bool GotoMap(Player p, string name) { + Level lvl = LevelInfo.FindExact(name); + if (lvl != null) return GotoLevel(p, lvl); + + if (Server.AutoLoad) { + // First try exactly matching unloaded levels + if (LevelInfo.ExistsOffline(name)) + return LoadOfflineLevel(p, name); + lvl = LevelInfo.Find(name); + if (lvl != null) return GotoLevel(p, lvl); + + string matches = LevelInfo.FindMapMatches(p, name); + if (matches == null) return false; + return LoadOfflineLevel(p, matches); + } else { + lvl = LevelInfo.Find(name); + if (lvl == null) { + Player.Message(p, "There is no level \"{0}\" loaded. Did you mean..", name); + Command.all.Find("search").Use(p, "levels " + name); + return false; + } + return GotoLevel(p, lvl); + } + } + + static bool LoadOfflineLevel(Player p, string name) { + if (!Level.CheckLoadOnGoto(name)) { + Player.Message(p, "Level \"{0}\" cannot be loaded using /goto.", name); + return false; + } + + CmdLoad.LoadLevel(p, name, "0", true); + Level lvl = LevelInfo.FindExact(name); + if (lvl != null) return GotoLevel(p, lvl); + + Player.Message(p, "Level \"{0}\" failed to be auto-loaded.", name); + return false; + } + + static bool GotoLevel(Player p, Level lvl) { + if (p.level == lvl) { Player.Message(p, "You are already in \"" + lvl.name + "\"."); return false; } + if (!lvl.CanJoin(p)) return false; + if (!Server.zombie.PlayerCanJoinLevel(p, lvl, p.level)) return false; + + p.Loading = true; + Entities.DespawnEntities(p); + Level oldLevel = p.level; + p.level = lvl; p.SendUserMOTD(); p.SendMap(oldLevel); + + ushort x = (ushort)(lvl.spawnx * 32 + 16); + ushort y = (ushort)(lvl.spawny * 32 + 32); + ushort z = (ushort)(lvl.spawnz * 32 + 16); + Entities.SpawnEntities(p, x, y, z, lvl.rotx, lvl.roty); + p.Loading = false; + CheckGamesJoin(p, oldLevel); + p.prevMsg = ""; + + if (!p.hidden && p.level.ShouldShowJoinMessage(oldLevel)) { + Player.SendChatFrom(p, p.color + "*" + p.DisplayName + " %Swent to &b" + lvl.name, false); + Player.RaisePlayerAction(p, PlayerAction.JoinWorld, lvl.name); + } + return true; + } + + internal static void CheckGamesJoin(Player p, Level oldLvl) { + Server.lava.PlayerJoinedLevel(p, p.level, oldLvl); + Server.zombie.PlayerJoinedLevel(p, p.level, oldLvl); + + if (p.inTNTwarsMap) p.canBuild = true; + TntWarsGame game = TntWarsGame.Find(p.level); + if (game == null) return; + + if (game.GameStatus != TntWarsGame.TntWarsGameStatus.Finished && + game.GameStatus != TntWarsGame.TntWarsGameStatus.WaitingForPlayers) { + p.canBuild = false; + Player.Message(p, "TNT Wars: Disabled your building because you are in a TNT Wars map!"); + } + p.inTNTwarsMap = true; + } + + static void Unload(Level lvl) { + bool unloadOld = true; + if (lvl.IsMuseum || !lvl.unload) return; + + Player[] players = PlayerInfo.Online.Items; + foreach (Player pl in players) { + if (pl.level == lvl) { unloadOld = false; break; } + } + if (unloadOld && Server.AutoLoad) lvl.Unload(true); } } } diff --git a/Player/Warp.cs b/Player/Warp.cs index 139eb549b..3474b7220 100644 --- a/Player/Warp.cs +++ b/Player/Warp.cs @@ -48,7 +48,7 @@ namespace MCGalaxy { Level lvl = LevelInfo.FindExact(wp.lvlname); if (p.level != lvl) - PlayerActions.ChangeMap(p, wp.lvlname); + PlayerActions.ChangeMap(p, lvl); if (p.level.name.CaselessEq(wp.lvlname)) { p.SendPos(0xFF, wp.x, wp.y, wp.z, wp.rotx, wp.roty);