void LeaveServer(string chatMsg, string discMsg, bool isKick, bool sync = false) { if (leftServer || IsSuper) { return; } leftServer = true; CriticalTasks.Clear(); ZoneIn = null; // Disconnected before sent handshake if (name == null) { if (Socket != null) { Socket.Close(); } Logger.Log(LogType.UserActivity, "{0} disconnected.", ip); return; } Server.reviewlist.Remove(name); try { if (Socket.Disconnected) { PlayerInfo.Online.Remove(this); return; } // FlyBuffer.Clear(); LastAction = DateTime.UtcNow; IsAfk = false; isFlying = false; if (weapon != null) { weapon.Disable(); } if (chatMsg != null) { chatMsg = Colors.Escape(chatMsg); } discMsg = Colors.Escape(discMsg); string kickPacketMsg = ChatTokens.Apply(discMsg, this); Send(Packet.Kick(kickPacketMsg, hasCP437), sync); Socket.Disconnected = true; ZoneIn = null; if (isKick) { TimesBeenKicked++; } if (!loggedIn) { PlayerInfo.Online.Remove(this); string user = name + " (" + ip + ")"; Logger.Log(LogType.UserActivity, "{0} disconnected. ({1})", user, discMsg); return; } Entities.DespawnEntities(this, false); ShowDisconnectInChat(chatMsg, isKick); save(); PlayerInfo.Online.Remove(this); OnPlayerDisconnectEvent.Call(this, discMsg); level.AutoUnload(); Dispose(); } catch (Exception e) { Logger.LogError("Error disconnecting player", e); } finally { Socket.Close(); } }
public void AddExtension(string Extension, int version) { switch (Extension.Trim()) { case CpeExt.ClickDistance: ClickDistance = version; break; case CpeExt.CustomBlocks: CustomBlocks = version; if (version == 1) { SendCustomBlockSupportLevel(1); } hasCustomBlocks = true; break; case CpeExt.HeldBlock: HeldBlock = version; break; case CpeExt.TextHotkey: TextHotKey = version; break; case CpeExt.ExtPlayerList: ExtPlayerList = version; hasExtList = version == 2; break; case CpeExt.EnvColors: EnvColors = version; break; case CpeExt.SelectionCuboid: SelectionCuboid = version; break; case CpeExt.BlockPermissions: BlockPermissions = version; break; case CpeExt.ChangeModel: UpdateModels(); ChangeModel = version; hasChangeModel = true; break; case CpeExt.EnvMapAppearance: EnvMapAppearance = version; break; case CpeExt.EnvWeatherType: EnvWeatherType = version; break; case CpeExt.HackControl: HackControl = version; break; case CpeExt.EmoteFix: EmoteFix = version; break; case CpeExt.MessageTypes: MessageTypes = version; break; case CpeExt.LongerMessages: LongerMessages = version; break; case CpeExt.FullCP437: FullCP437 = version; break; case CpeExt.BlockDefinitions: BlockDefinitions = version; hasBlockDefs = true; break; case CpeExt.BlockDefinitionsExt: BlockDefinitionsExt = version; break; case CpeExt.TextColors: hasTextColors = true; TextColors = version; for (int i = 0; i < Colors.ExtColors.Length; i++) { if (Colors.ExtColors[i].Undefined) { continue; } Colors.SendSetTextColor(this, Colors.ExtColors[i]); } break; case CpeExt.BulkBlockUpdate: BulkBlockUpdate = version; break; } }
void LeaveServer(string chatMsg, string discMsg, bool isKick, bool sync = false) { if (leftServer) { return; } leftServer = true; CriticalTasks.Clear(); //Umm...fixed? if (name == null || name.Length == 0) { if (Socket != null) { CloseSocket(); } connections.Remove(this); disconnected = true; Logger.Log(LogType.UserActivity, "{0} disconnected.", ip); return; } Server.reviewlist.Remove(name); try { if (disconnected) { CloseSocket(); connections.Remove(this); PlayerInfo.Online.Remove(this); return; } // FlyBuffer.Clear(); LastAction = DateTime.UtcNow; IsAfk = false; isFlying = false; aiming = false; if (chatMsg != null) { chatMsg = Colors.Escape(chatMsg); } discMsg = Colors.Escape(discMsg); string kickPacketMsg = ChatTokens.Apply(discMsg, this); Send(Packet.Kick(kickPacketMsg, hasCP437), sync); disconnected = true; if (isKick) { TimesBeenKicked++; } if (!loggedIn) { connections.Remove(this); RemoveFromPending(); PlayerInfo.Online.Remove(this); string user = name + " (" + ip + ")"; Logger.Log(LogType.UserActivity, "{0} disconnected. ({1})", user, discMsg); return; } if (Game.team != null) { Game.team.RemoveMember(this); } TntWarsGame tntwarsgame = TntWarsGame.GameIn(this); if (tntwarsgame != null) { tntwarsgame.Players.Remove(tntwarsgame.FindPlayer(this)); tntwarsgame.SendAllPlayersMessage("TNT Wars: " + ColoredName + " %Shas left TNT Wars!"); } Entities.DespawnEntities(this, false); ShowDisconnectInChat(chatMsg, isKick); save(); PlayerInfo.Online.Remove(this); Server.PlayerListUpdate(); OnPlayerDisconnectEvent.Call(this, discMsg); if (ServerConfig.AutoLoadMaps && level.Config.AutoUnload && !level.IsMuseum && !level.HasPlayers()) { level.Unload(true); } Dispose(); } catch (Exception e) { Logger.LogError(e); } finally { CloseSocket(); } }
// TODO: Optimize this using a StringBuilder public static List <string> Wordwrap(string message) { List <string> lines = new List <string>(); message = Regex.Replace(message, @"(&[0-9a-f])+(&[0-9a-f])", "$2"); message = Regex.Replace(message, @"(&[0-9a-f])+$", ""); int limit = NetUtils.StringSize; string color = ""; while (message.Length > 0) { //if (Regex.IsMatch(message, "&a")) break; if (lines.Count > 0) { if (message[0] == '&') { message = "> " + message.Trim(); } else { message = "> " + color + message.Trim(); } } if (message.IndexOf("&") == message.IndexOf("&", message.IndexOf("&") + 1) - 2) { message = message.Remove(message.IndexOf("&"), 2); } if (message.Length <= limit) { lines.Add(message); break; } for (int i = limit - 1; i > limit - 20; --i) { if (message[i] == ' ') { lines.Add(message.Substring(0, i)); goto Next; } } retry: if (message.Length == 0 || limit == 0) { return(lines); } try { if (message.Substring(limit - 2, 1) == "&" || message.Substring(limit - 1, 1) == "&") { message = message.Remove(limit - 2, 1); limit -= 2; goto retry; } else if (message[limit - 1] < 32 || message[limit - 1] > 127) { message = message.Remove(limit - 1, 1); limit -= 1; //goto retry; } } catch { return(lines); } lines.Add(message.Substring(0, limit)); Next : message = message.Substring(lines[lines.Count - 1].Length); if (lines.Count == 1) { limit = 60; } int index = lines[lines.Count - 1].LastIndexOf('&'); if (index != -1) { if (index < lines[lines.Count - 1].Length - 1) { char next = lines[lines.Count - 1][index + 1]; if (Colors.Map(ref next)) { color = "&" + next; } if (index == lines[lines.Count - 1].Length - 1) { lines[lines.Count - 1] = lines[lines.Count - 1].Substring(0, lines[lines.Count - 1].Length - 2); } } else if (message.Length != 0) { char next = message[0]; if (Colors.Map(ref next)) { color = "&" + next; } lines[lines.Count - 1] = lines[lines.Count - 1].Substring(0, lines[lines.Count - 1].Length - 1); message = message.Substring(1); } } } for (int i = 0; i < lines.Count; i++) // Gotta do it the old fashioned way... { char[] temp = lines[i].ToCharArray(); if (temp[temp.Length - 2] == '&') { temp[temp.Length - 1] = ' '; temp[temp.Length - 2] = ' '; } lines[i] = new string(temp); } return(lines); }
static string TokenName(Player p) { return((Server.Config.DollarNames ? "$" : "") + Colors.Strip(p.DisplayName)); }
static bool ValidColor(char c) { return(Colors.IsStandard(c) || Colors.IsDefined(c)); }
/// <summary> Removes redundant colour codes and fixes some colour codes to behave correctly for older clients </summary> /// <param name="fullAmpersands"> if false, ampersands not followed by valid colour code are removed </param> /// <param name="customCols"> if false, converts custom colour codes into fallback colour code </param> public static string CleanupColors(string value, bool fullAmpersands, bool customCols) { if (value.IndexOf('&') == -1) { return(value); } StringBuilder sb = new StringBuilder(value.Length); int lastIdx = -1; char lastCol = 'f', col; bool combinable = false; for (int i = 0; i < value.Length; i++) { char c = value[i]; // Definitely not a colour code if (c != '&') { if (c != ' ') { combinable = false; } sb.Append(c); continue; } // Maybe still not a colour code if (i == value.Length - 1 || (col = Colors.Lookup(value[i + 1])) == '\0') { // Treat the & like a normal character // For clients not supporting standalone '&', show '%' instead combinable = false; sb.Append(fullAmpersands ? '&' : '%'); continue; } if (!customCols) { col = Colors.Get(col).Fallback; } // Don't append duplicate colour codes if (lastCol != col) { // Remove first colour code in "&a&b or "&a &b" if (combinable) { sb.Remove(lastIdx, 2); } sb.Append('&').Append(col); lastIdx = sb.Length - 2; lastCol = col; combinable = true; } i++; // skip over color code } // Trim trailing color codes while (sb.Length >= 2) { if (sb[sb.Length - 2] != '&') { break; } if (Colors.Lookup(sb[sb.Length - 1]) == '\0') { break; } // got a color code at the end, remove sb.Remove(sb.Length - 2, 2); } return(sb.ToString()); }
/// <summary> Parses the MOTD flags and returns resulting HackControl packet. </summary> ///<remarks> "+ophax" permission is determined by p.Rank >= LevelPermission.Operator </remarks> public static byte[] MakeHackControl(Player p, string motd) { motd = Colors.Strip(motd); bool isOp = p.Rank >= LevelPermission.Operator; bool fly = true, noclip = true, speed = true, respawn = true, thirdPerson = true; short maxJump = -1; string[] parts = motd.SplitSpaces(); for (int i = 0; i < parts.Length; i++) { string part = parts[i]; if (part.CaselessEq("-hax") || (part.CaselessEq("-ophax") && isOp)) { fly = false; noclip = false; speed = false; respawn = false; thirdPerson = false; } else if (part.CaselessEq("+hax") || (part.CaselessEq("+ophax") && isOp)) { fly = true; noclip = true; speed = true; respawn = true; thirdPerson = true; } else if (part.CaselessEq("+noclip")) { noclip = true; } else if (part.CaselessEq("+fly")) { fly = true; } else if (part.CaselessEq("+speed")) { speed = true; } else if (part.CaselessEq("+respawn")) { respawn = true; } else if (part.CaselessEq("+thirdperson")) { thirdPerson = true; } else if (part.CaselessEq("-noclip")) { noclip = false; } else if (part.CaselessEq("-fly")) { fly = false; } else if (part.CaselessEq("-speed")) { speed = false; } else if (part.CaselessEq("-respawn")) { respawn = false; } else if (part.CaselessEq("-thirdperson")) { thirdPerson = false; } if (!part.CaselessStarts("jumpheight=")) { continue; } string heightPart = part.Substring(part.IndexOf('=') + 1); float value; if (Utils.TryParseSingle(heightPart, out value)) { maxJump = (short)(value * 32); } } return(Packet.HackControl(fly, noclip, speed, respawn, thirdPerson, maxJump)); }
/// <summary> Attempts to change the color of the target player </summary> public static bool SetColor(Player p, string target, string name) { string color = ""; Player who = PlayerInfo.FindExact(target); if (name.Length == 0) { color = Group.GroupIn(target).Color; PlayerDB.Update(target, PlayerData.ColumnColor, ""); MessageAction(p, target, who, "λACTOR &Sremoved λTARGET color"); } else { color = Matcher.FindColor(p, name); if (color == null) { return(false); } PlayerDB.Update(target, PlayerData.ColumnColor, color); MessageAction(p, target, who, "λACTOR &Schanged λTARGET color to " + color + Colors.Name(color)); } if (who != null) { who.UpdateColor(color); } return(true); }
/// <summary> Attempts to change the title color of the target player </summary> public static bool SetTitleColor(Player p, string target, string name) { string color = ""; Player who = PlayerInfo.FindExact(target); if (name.Length == 0) { MessageAction(p, target, who, "λACTOR &Sremoved λTARGET title color"); } else { color = Matcher.FindColor(p, name); if (color == null) { return(false); } MessageAction(p, target, who, "λACTOR &Schanged λTARGET title color to " + color + Colors.Name(color)); } if (who != null) { who.titlecolor = color; } if (who != null) { who.SetPrefix(); } PlayerDB.Update(target, PlayerData.ColumnTColor, color); return(true); }