// Code to run when used by a player public override void Use(Player p, string message) { if (message != "list") { if (Server.afkset.Contains(p.name)) { Server.afkset.Remove(p.name); Player.GlobalMessage("-" + p.group.Color + p.name + "&e- is no longer AFK"); IRCBot.Say(p.name + " is no longer AFK"); } else { Server.afkset.Add(p.name); Player.GlobalMessage("-" + p.group.Color + p.name + "&e- is AFK " + message); IRCBot.Say(p.name + " is AFK " + message); } } else { // Send list of afk players foreach (string s in Server.afkset) { p.SendMessage(s); } } }
// Code to run when used by the console public override void Use(string message) { if (message != "") { string who = message; int index = message.IndexOf(' '); if (index != -1) { who = message.Substring(0, index); message = message.Substring(index + 1); } if (Player.Exists(who)) { Player target = Player.Find(who); if (index == -1) { target.Kick("You were kicked by [console]!"); IRCBot.Say(who + " was kicked by [console]"); } else { target.Kick(message); IRCBot.Say(who + " was kicked (" + message + ")"); } } } }
// Code to run when used by a player public override void Use(Player p, string message) { if (message != "") { string who = message; int index = message.IndexOf(' '); if (index != -1) { who = message.Substring(0, index); message = message.Substring(index + 1); } // Find the player and ensure they are online Player target = Player.Find(who); if (target != null) { if (p.Rank > target.Rank) { if (target != p) { if (index == -1) { target.Kick("You were kicked by " + p.name + "!"); IRCBot.Say(who + " was kicked by " + p.name); } else { target.Kick(message); IRCBot.Say(who + " was kicked by " + p.name + "(" + message + ")"); } } else { p.SendMessage("You can't kick yourself!"); } } else { p.SendMessage("You can't kick someone of equal or higher rank!"); } } else { p.SendMessage("There is no player called \"" + who + "\" currently online!"); } } else { Help(p); } }
/// <summary> /// Handles a player disconnection. Cleans up the player from other players on the server /// as well as handles cleaning up the player from the system. /// </summary> public void Disconnect() { if (disconnected) { if (connections.Contains(this)) { connections.Remove(this); } return; } disconnected = true; pingTimer.Stop(); SendKick("Disconnected."); if (loggedIn) { GlobalDie(this, false); if (!hidden) { GlobalChat(this, "&c- " + color + name + "&e disconnected.", false); } IRCBot.Say(name + " left the game."); Logger.Log(name + " disconnected."); players.Remove(this); /*if (!Server.console && Server.win != null) * Server.win.UpdateClientList(players);*/ left.Add(this.name.ToLower(), this.ip); //Added by bman for lastseen command if (!lastSeen.ContainsKey(this.name.ToLower())) { lastSeen.Add(this.name.ToLower(), DateTime.Now); Server.SaveLastSeen(); } else { lastSeen[this.name.ToLower()] = DateTime.Now; Server.SaveLastSeen(); } } else { connections.Remove(this); Logger.Log(ip + " disconnected."); } if (Server.afkset.Contains(name)) { Server.afkset.Remove(name); } //Removes from afk list on disconnect }
// Code to run when used by a player public override void Use(Player p, string message) { if (message != "") { message = "&e" + message; // defaults to yellow message = message.Replace("%", "&"); // Allow colors in global messages Player.GlobalChat(p, message, false); message = message.Replace("&", ""); // converts the MC color codes to IRC. Doesn't seem to work with multiple colors IRCBot.Say("Global: " + message); } else { Help(p); } }
// Code to run when used by a player public override void Use(Player p, string message) { if (message != "") { try { int temp = int.Parse(message); if (temp >= 0 && temp <= 2) { p.level.Physics = (Physics)temp; switch (p.level.Physics) { case Physics.Off: p.level.ClearPhysics(); Player.GlobalMessageLevel(p.level, "Physics is now &cOFF&e on &b" + p.level.name + "&e."); Logger.Log("Physics is now OFF on " + p.level.name + "."); IRCBot.Say("Physics is now OFF on " + p.level.name + "."); break; case Physics.Normal: Player.GlobalMessageLevel(p.level, "Physics is now &aNormal&e on &b" + p.level.name + "&e."); Logger.Log("Physics is now ON on " + p.level.name + "."); IRCBot.Say("Physics is now ON on " + p.level.name + "."); break; case Physics.Advanced: Player.GlobalMessageLevel(p.level, "Physics is now &aAdvanced&e on &b" + p.level.name + "&e."); Logger.Log("Physics is now ADVANCED on " + p.level.name + "."); IRCBot.Say("Physics is now ADVANCED on " + p.level.name + "."); break; } } else { p.SendMessage("Not a valid setting"); } } catch { p.SendMessage("INVALID INPUT"); } } else { Help(p); } }
// Code to run when used by a player public override void Use(Player p, string message) { if (message != "") { string[] split = message.Split(' '); string newmsg = ""; Player target = Player.Find(split[0]); if (target != null) { // Make sure we have a message to send foreach (string s in split) { if (s != split[0] && s.Trim() != "") { newmsg = newmsg + s + " "; } } newmsg.Trim(); if (newmsg.Length > 0) { Player.GlobalChat(target, newmsg); Logger.Log("<" + target.name + "> " + newmsg, LogType.UserCommand); IRCBot.Say(target.name + ": " + newmsg); } else { p.SendMessage("Error: You need a message to send!"); } } else { p.SendMessage(LanguageString.NoSuchPlayer); } } else { Help(p); } }
/// <summary> /// Handles a player blockchange packet /// </summary> /// <param name="message">The blockchange packet</param> void HandleBlockchange(byte[] message) { try { // Bots are not allows making block changes if (group.Name == "bots") { return; } // Players who are not logged in cannot if (!loggedIn) { return; } // Players who spam can't make block changes if (CheckBlockSpam()) { return; } // Get the packet information ushort x = NTHO(message, 0); ushort y = NTHO(message, 2); ushort z = NTHO(message, 4); byte action = message[6]; byte newBlockType = message[7]; // If the client is trying to place a block > 49, it's either: // - A new version (unlikely) // - A hacked client (much more likely) if (newBlockType > 49) { Kick("Unknown block type!"); return; } // Get the block that we're trying to change byte targetBlockType = level.GetTile(x, y, z); // Chan't changed a block type of Zero if (targetBlockType == Block.Zero) { return; } // Check to see if the player is allowed editing the map if (group.Permission < level.permissionbuild) { SendMessage("Your not allowed to edit this map."); // Replace the block we just destroyed SendBlockchange(x, y, z, targetBlockType); return; } // Check to see if we have a block change to process // Blockchange actions now have priority, allowing people to /about blocks they cant change if (Blockchange != null) { Blockchange(this, x, y, z, newBlockType); return; } // Check to see if the permission on the level is guest // If the permission is guest, then we check to make sure no hacked clients are messing with the map // TODO: I'm not sure this should only apply to guests -- Voziv -- if (group.Permission == LevelPermission.Guest) { // Let banned players greif if (Rank == GroupEnum.Banned) //Just let them think theyre are griefing instead. { return; } // Get the distance that the user is trying to place the block int Diff = 0; Diff = Math.Abs((int)(pos[0] / 32) - x); Diff += Math.Abs((int)(pos[1] / 32) - y); Diff += Math.Abs((int)(pos[2] / 32) - z); // TODO: This gets triggered by WOM and possible the normal minecraft client. I'm thinking we should just leave it at 10 blocks they get kicked if (Diff > 9) //Danger level compensation { if (Diff > 10) //Too much distance { Logger.Log(name + " attempted to build with a " + Diff.ToString() + " distance offset", LogType.SuspiciousActivity); GlobalMessageOps("To Ops &f-" + color + name + "&f- attempted to build with a " + Diff.ToString() + " distance offset"); Kick("Hacked client."); return; } SendMessage("You cant build that far away."); SendBlockchange(x, y, z, targetBlockType); return; } // Make sure kids aren't anti tunnelling if (Properties.AntiTunnelEnabled) { if (y < level.depth / 2 - Properties.MaxDepth) //Anti tunneling countermeasure { SendMessage("You're not allowed to build this far down!"); SendBlockchange(x, y, z, targetBlockType); return; } } } // More anti hax - Check to see if we are deleting adminium if (targetBlockType == Block.blackrock) //Check for client hacker trying to delete adminium { // Ops are allowed to delete adminium if (!checkOp()) { Logger.Log(name + " attempted to delete an adminium block.", LogType.SuspiciousActivity); GlobalMessageOps("To Ops &f-" + color + name + "&f- attempted to delete an adminium block."); Kick("Hacked client."); return; } } // Special Blocks that only operators can delete if (targetBlockType >= 100 && !doors.doorBlocks.Contains(targetBlockType)) { if (!checkOp()) { SendMessage("You're not allowed to destroy this block!"); SendBlockchange(x, y, z, targetBlockType); return; } //Special blocks that should never be replaced until they are finished if (targetBlockType >= 200) { SendMessage("Block is active, you cant disturb it!"); SendBlockchange(x, y, z, targetBlockType); return; } } // If the block is not placable by the current player, deny them if (!Block.Placable(newBlockType)) { SendMessage("You can't place this block type!"); SendBlockchange(x, y, z, targetBlockType); return; } // Validate the action coming from the client if (action > 1) { Kick("Unknown block action!"); } newBlockType = bindings[newBlockType]; //Ignores updating blocks that are the same and send block only to the player // If we are trying to place or paint a target block that is the same as the block // that is there, then we ignore it if (targetBlockType == (byte)((painting || action == 1) ? newBlockType : 0)) { if (painting || message[7] != newBlockType) { SendBlockchange(x, y, z, targetBlockType); } return; } // Action Processing // 0 == Deletion // 1 == Placement // Delete block requests only go through if we are not painting if (!painting && action == 0) { // Warn the server if the player places a block around the spawn area if ((x == level.spawnx) && (y == level.spawny - 1) && (z == level.spawnz)) // if player deletes the spawn block or adjacent-ish { Player.GlobalChat(this, (this.name + " has deleted a spawn block."), false); IRCBot.Say("Global: " + (this.name + " has deleted a spawn block.")); } if ((x == level.spawnx) && (y == level.spawny - 2) && (z == level.spawnz)) { Player.GlobalChat(this, (this.name + " has deleted a spawn block."), false); IRCBot.Say("Global: " + (this.name + " has deleted a spawn block.")); } deleteBlock(targetBlockType, newBlockType, x, y, z); } else //player is placing a block { if ((x == level.spawnx) && (y == level.spawny - 1) && (z == level.spawnz)) // if player deletes the spawn block or adjacent-ish { Player.GlobalChat(this, (this.name + " has deleted a spawn block."), false); IRCBot.Say("Global: " + (this.name + " has deleted a spawn block.")); } if ((x == level.spawnx) && (y == level.spawny - 2) && (z == level.spawnz)) { Player.GlobalChat(this, (this.name + " has deleted a spawn block."), false); IRCBot.Say("Global: " + (this.name + " has deleted a spawn block.")); } placeBlock(targetBlockType, newBlockType, x, y, z); } } catch (Exception e) { Logger.Log(name + " has triggered a block change error", LogType.Error); Logger.Log(e.Message, LogType.ErrorMessage); GlobalMessageOps(name + " has triggered a block change error"); IRCBot.Say(name + " has triggered a block change error"); } }
/// <summary> /// Handles a player login packet /// </summary> /// <param name="message">The login packet</param> void HandleLogin(byte[] message) { try { //byte[] message = (byte[])m; if (loggedIn) { return; } byte version = message[0]; name = Encoding.ASCII.GetString(message, 1, 64).Trim(); string verify = Encoding.ASCII.GetString(message, 65, 32).Trim(); byte type = message[129]; if (Server.banned.Contains(name)) { Kick("You're banned!"); return; } if (Player.players.Count >= Properties.MaxPlayers) { Kick("Server full!"); return; } if (version != MinecraftClassicProtocolVersion) { Kick("Wrong version!"); return; } if (name.Length > 16 || !ValidName(name)) { Kick("Illegal name!"); return; } if (Properties.VerifyNames) { if (verify == "--" || verify != BitConverter.ToString( MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(Server.salt + name))). Replace("-", "").ToLower().TrimStart('0')) { if (ip != "127.0.0.1") { Kick("Login failed! Try again."); return; } } } Player old = Player.Find(name); Logger.Log(ip + " logging in as " + name + "."); if (old != null) { if (Properties.VerifyNames) { old.Kick("Someone else logged in as " + name + ". Duplicate logins are not allowed!"); } else { Kick("Already logged in!"); return; } } left.Remove(name.ToLower()); if (Properties.ServerAdministrator == name) { group = Group.Find("administrator"); } else if (Server.bot.Contains(name)) { group = Group.Find("bots"); } else if (Server.operators.Contains(name)) { group = Group.Find("operator"); } else if (Server.moderators.Contains(name)) { group = Group.Find("moderator"); } else if (Server.advbuilders.Contains(name)) { group = Group.Find("advbuilder"); } else if (Server.builders.Contains(name)) { group = Group.Find("builder"); } else { group = Group.standard; } SendMotd(); SendMap(); if (disconnected) { return; } loggedIn = true; id = FreeId(); players.Add(this); connections.Remove(this); GlobalChat(this, "&a+ " + color + name + "&e joined the game.", false); /* * if (!Server.console && Server.win != null) * Server.win.UpdateClientList(players); */ IRCBot.Say(name + " joined the game."); //Test code to show wehn people come back with different accounts on the same IP string temp = "Lately known as:"; bool found = false; if (ip != "127.0.0.1") { foreach (KeyValuePair <string, string> prev in left) { if (prev.Value == ip) { found = true; temp += " " + prev.Key; } } if (found) { GlobalMessageOps(temp); Logger.Log(temp); IRCBot.Say(temp); } } 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 }; GlobalSpawn(this, x, y, z, rot[0], rot[1], true); foreach (Player p in players) { if (p.level == level && p != this && !p.hidden) { SendSpawn(p.id, p.color + p.name, p.pos[0], p.pos[1], p.pos[2], p.rot[0], p.rot[1]); } } Loading = false; } catch (Exception e) { Logger.Log(e.Message, LogType.ErrorMessage); Player.GlobalMessage("An error occurred: " + e.Message); } }
// Code to run when used by a player public override void Use(Player p, string message) { if (message == "") { Help(p); return; } string[] commands = message.Split(' '); switch (commands[0]) { case "set": { p.level.jailedX = p.pos[0]; p.level.jailedY = p.pos[1]; p.level.jailedZ = p.pos[2]; p.level.jailedRotX = p.rot[0]; p.level.jailedRotY = p.rot[1]; p.SendMessage("Jail location successfully set at your position"); break; } case "add": { if (commands.Length != 2) { Help(p); return; } Player who = Player.Find(commands[1]); if (who == null) //check for valid player { p.SendMessage("Player not found!"); return; } if (who.level.jailedX == 0 && who.level.jailedY == 0) //Check for valid jail position { p.SendMessage("No jail position set for that level! Go set one!"); return; } if (who.isJailed) { p.SendMessage(who.name + " is already in jail!"); } else { who.level.jailedPlayers.Add(who); who.isJailed = true; //This prevents the jailed user from using goto Player.GlobalMessage("-" + who.color + who.name + "&e is now JAILED on &2" + who.level.name + "! &eEveryone point and laugh!"); IRCBot.Say(who.name + " was just JAILED on " + who.level.name); } break; } case "free": { if (commands.Length != 2) { Help(p); return; } Player who = Player.Find(commands[1]); if (!who.level.jailedPlayers.Remove(who)) //check for success { p.SendMessage("Player not found!"); return; } who.isJailed = false; //User can use goto again who.SendMessage("You have been freed!"); Player.GlobalMessage("-" + who.color + who.name + "&e has been let out of jail!"); IRCBot.Say(who.name + " has been let out of jail!"); break; } default: Help(p); break; } }
// Code to run when used by a player public override void Use(Player p, string message) { Regex regex = new Regex(@"^([0-9]{1,3}\.){3}[0-9]{1,3}$"); if (message == "") { if (p != null) { Help(p); } return; } Player who = null; who = Player.Find(message); if (who != null) { message = who.ip; } if (message.Equals("127.0.0.1")) { if (p != null) { p.SendMessage("You can't ip-ban the server!"); } return; } if (!regex.IsMatch(message)) { if (p != null) { p.SendMessage("Not a valid ip!"); } return; } if (p != null) { if (p.ip == message) { p.SendMessage("You can't ip-ban yourself.!"); return; } } if (Server.bannedIP.Contains(message)) { if (p != null) { p.SendMessage(message + " is already ip-banned."); } return; } Player.GlobalMessage(message + " got &8ip-banned&e!"); if (p != null) { IRCBot.Say("IP-BANNED: " + message.ToLower() + " by " + p.name); } else { IRCBot.Say("IP-BANNED: " + message.ToLower() + " by console"); } Server.bannedIP.Add(message); Logger.Log("IP-BANNED: " + message.ToLower()); List <Player> kickList = new List <Player>(); foreach (Player pl in Player.players) { if (message.Equals(pl.ip)) { kickList.Add(pl); } //Kicks anyone off with matching ip for convinience } foreach (Player pl in kickList) { pl.Kick("Kicked by ipban"); } }
// Code to run when used by a player public override void Use(Player p, string message) { if (message != "") { string who = message; int index = message.IndexOf(' '); string kickmessage = "kicked and banned by " + p.name + "! ("; if (index != -1) { who = message.Substring(0, index); kickmessage += message.Substring(index + 1) + ")"; } else { kickmessage += "Kicked + Banned!)"; } Player target = Player.Find(who); if (!Server.banned.Contains(who)) { if (p.Rank > Player.GetRank(who)) { if (target != null) { if (target != p) { target.Kick(kickmessage); Player.Ban(who); } else { p.SendMessage("You can't kickban yourself!"); } } else { Player.Ban(who); Player.GlobalMessage(target.name + " was " + kickmessage); IRCBot.Say(target.name + " was " + kickmessage); } } else { p.SendMessage("You can't kickban someone of equal or higher rank!"); } } else { p.SendMessage(who + " is already banned."); if (target != null) { target.Kick(kickmessage); } } } else { Help(p); } }
void HandleChat(byte[] message) { try { if (!loggedIn) { return; } if (!group.CanChat) { return; } //byte[] message = (byte[])m; string text = Encoding.ASCII.GetString(message, 1, 64).Trim(); //added by bman if (this.isMuted) { Logger.Log("(Muted) " + name + ": " + text); return; } //Added by bman - Joker command if (isJoker) { if (DateTime.Now.Subtract(lastJoke).TotalSeconds > 3) { Logger.Log("(Joker) " + name + ": " + text, LogType.WorldChat); text = Server.jokerMessages[rand.Next(0, Server.jokerMessages.Count)]; lastJoke = DateTime.Now; } else { SendMessage("*Anti-Spam*"); return; } } text = Regex.Replace(text, @"\s\s+", " "); foreach (char ch in text) { if (ch < 32 || ch >= 127 || ch == '&') { Kick("Illegal character in chat message!"); return; } } if (text.Length == 0) { return; } if (text[0] == '/') { text = text.Remove(0, 1); int pos = text.IndexOf(' '); if (pos == -1) { HandleCommand(text.ToLower(), ""); return; } string cmd = text.Substring(0, pos).ToLower(); string msg = text.Substring(pos + 1); HandleCommand(cmd, msg); return; } if ((text[0] == '@' || isWhisperChat) && (text[0] != '#')) // if the user has # in front of their text, manual overide { string newtext = ""; string to = whisperTarget; string msg = text; if (!isWhisperChat) { newtext = text.Substring(1).Trim(); int pos = newtext.IndexOf(' '); if (pos != -1) { to = newtext.Substring(0, pos); msg = newtext.Substring(pos + 1); } } HandleQuery(to, msg); Logger.Log("<" + name + "> to <" + to + ">" + newtext, LogType.PrivateChat); return; } if ((text[0] == '#') || (isOpChat)) // no overide check is needed here because the "@" whisper check occurs before this code. { string newtext = text; if (!isOpChat) { newtext = text.Remove(0, 1).Trim(); } GlobalMessageOps("To Ops &f-" + color + name + "&f- " + newtext); if (!checkOp()) { SendMessage("To Ops &f-" + color + name + "&f- " + newtext); } Logger.Log("<" + name + "> " + newtext, LogType.OpChat); return; } if (text[0] == '%') { string newtext = text.Remove(0, 1).Trim(); if (!Properties.AllowWorldChat) { GlobalChatWorld(this, newtext, true); Logger.Log("<" + name + "> " + newtext, LogType.WorldChat); } else { GlobalChat(this, newtext); Logger.Log("<" + name + "> " + newtext, LogType.GlobalChat); } IRCBot.Say("<" + name + "> " + newtext); return; } if (Properties.AllowWorldChat) { GlobalChat(this, text); Logger.Log("<" + name + "> " + text, LogType.WorldChat); } else { GlobalChatLevel(this, text, true); Logger.Log("<" + name + "> " + text, LogType.GlobalChat); } IRCBot.Say(name + ": " + text); } catch (Exception e) { Logger.Log("There was an error with chat.", LogType.Error); Logger.Log(e.Message, LogType.ErrorMessage); } }
// Code to run when used by a player public override void Use(Player p, string message) { if (message == "") { Help(p); } else { bool stealth = false; if (message[0] == '#') { message = message.Remove(0, 1).Trim(); stealth = true; Logger.Log("Stealth Ban Atempted"); } // Ensure the name is valid if (Player.ValidName(message)) { // Ensure the player isn't banned already if (Player.GetRank(message) != GroupEnum.Banned) { if (p.Rank > Player.GetRank(message)) { // Check to see if the player is online // Send appropriate message based on status and stealth option if (Player.IsOnline(message)) { if (stealth) { } else { Player.GlobalMessage("[Server]:" + p.color + p.name + "&e has banned " + message); } } else { Player.GlobalMessage("[Server]:" + p.color + p.name + "&e has banned " + message + "(offline)"); } // Actually get around to banning the player Player.Ban(message); IRCBot.Say(message + " was banned"); } else { p.SendMessage("You can't ban someone of equal or higher rank!"); } } else { p.SendMessage(message + " is already banned."); } } else { p.SendMessage("Invalid name \"" + message + "\"."); } } }