public async Task OnMessageEdited(Cacheable <IMessage, ulong> message, SocketMessage m, ISocketMessageChannel channel) { if (m is not SocketUserMessage msg) { return; } if (msg.Author.IsBot) { return; } IMessage message2 = await message.GetOrDownloadAsync(); if (message2.Content != msg.Content && channel is SocketTextChannel textChannel) { if (Extensions.GetLogChannel(textChannel.Guild) != null && channel != Extensions.GetLogChannel(textChannel.Guild)) { if (DiscordStaff.Get(textChannel.Guild.Id, "u-" + msg.Author.Id).Count <= 0 || (textChannel.Guild.GetUser(msg.Author.Id).Roles.Count > 1 && DiscordStaff.Get(textChannel.Guild.Id, "r-" + textChannel.Guild.GetUser(msg.Author.Id).Roles.Where(x => x.IsEveryone == false).OrderBy(x => x.Position).First().Id).Count > 0)) { AutoMod mod = new AutoMod(_client); await mod.FilterMessage(msg, textChannel); } } } }
private void VentContainer(bool isOpen) { container.Opened = isOpen; if (isOpen) { StartCoroutine(DisplayFlashingText($"Canister releasing at {container.ReleasePressure}")); Canister canister = Provider.GetComponent <Canister>(); if (canister.ContentsName.Contains("Plasma")) { foreach (var p in Peepers) { AutoMod.ProcessPlasmaRelease(p); } } } }
private void VentContainer(bool isOpen) { canister.SetValve(isOpen); if (canister.GasContainer.IsVenting) { StartCoroutine(DisplayFlashingText($"Canister releasing at {gasContainer.ReleasePressure}")); if (canister.ContentsName.Contains("Plasma")) { foreach (var p in Peepers) { AutoMod.ProcessPlasmaRelease(p); } } } }
/// <summary> /// Send a Chat Msg from a player to the selected Chat Channels /// Server only /// </summary> public static void AddChatMsgToChat(ConnectedPlayer sentByPlayer, string message, ChatChannel channels) { message = AutoMod.ProcessChatServer(sentByPlayer, message); if (string.IsNullOrWhiteSpace(message)) { return; } var player = sentByPlayer.Script; // The exact words that leave the player's mouth (or that are narrated). Already includes HONKs, stutters, etc. // This step is skipped when speaking in the OOC channel. (string message, ChatModifier chatModifiers)processedMessage = (string.Empty, ChatModifier.None); // Placeholder values bool isOOC = channels.HasFlag(ChatChannel.OOC); if (!isOOC) { processedMessage = ProcessMessage(sentByPlayer, message); } var chatEvent = new ChatEvent { message = isOOC ? message : processedMessage.message, modifiers = (player == null) ? ChatModifier.None : processedMessage.chatModifiers, speaker = (player == null) ? sentByPlayer.Username : player.name, position = ((player == null) ? TransformState.HiddenPos : player.WorldPos), channels = channels, originator = sentByPlayer.GameObject }; if (channels.HasFlag(ChatChannel.OOC)) { chatEvent.speaker = sentByPlayer.Username; if (PlayerList.Instance.IsAdmin(sentByPlayer.UserId)) { chatEvent.speaker = "[Admin] " + chatEvent.speaker; } Instance.addChatLogServer.Invoke(chatEvent); return; } // TODO the following code uses player.playerHealth, but ConciousState would be more appropriate. // Check if the player is allowed to talk: if (player != null && player.playerHealth != null) { if (player.playerHealth.IsCrit || player.playerHealth.IsCardiacArrest) { if (!player.playerHealth.IsDead) { return; } else { channels = ChatChannel.Ghost; } } else if (!player.playerHealth.IsDead && !player.IsGhost) { //Control the chat bubble player.playerNetworkActions.CmdToggleChatIcon(true, processedMessage.message, channels, processedMessage.chatModifiers); } } // There could be multiple channels we need to send a message for each. // We do this on the server side that local chans can be determined correctly foreach (Enum value in Enum.GetValues(channels.GetType())) { if (channels.HasFlag((ChatChannel)value)) { //Using HasFlag will always return true for flag at value 0 so skip it if ((ChatChannel)value == ChatChannel.None) { continue; } if (IsNamelessChan((ChatChannel)value)) { continue; } chatEvent.channels = (ChatChannel)value; Instance.addChatLogServer.Invoke(chatEvent); } } }
/// <summary> /// Actions the server performs when the player dies /// </summary> protected override void OnDeathActions() { if (CustomNetworkManager.Instance._isServer) { ConnectedPlayer player = PlayerList.Instance.Get(gameObject, true); string killerName = null; if (LastDamagedBy != null) { var lastDamager = PlayerList.Instance.Get(LastDamagedBy, true); if (lastDamager != null) { killerName = lastDamager.Name; AutoMod.ProcessPlayerKill(lastDamager, player); } } if (killerName == null) { killerName = "stressful work"; } string playerName = player?.Name ?? "dummy"; if (killerName == playerName) { Chat.AddActionMsgToChat(gameObject, "You committed suicide, what a waste.", $"{playerName} committed suicide."); } else if (killerName.EndsWith(playerName)) { string themself = null; if (player != null) { themself = player.CharacterSettings?.ThemselfPronoun(player.Script); } if (themself == null) { themself = "themself"; } //chain reactions Chat.AddActionMsgToChat(gameObject, $"You screwed yourself up with some help from {killerName}", $"{playerName} screwed {themself} up with some help from {killerName}"); } else { PlayerList.Instance.TrackKill(LastDamagedBy, gameObject); } //drop items in hand if (dynamicItemStorage != null) { foreach (var itemSlot in dynamicItemStorage.GetHandSlots()) { Inventory.ServerDrop(itemSlot); } } if (isServer) { //TODO: Re - impliment this using the new reagent- first code introduced in PR #6810 //EffectsFactory.BloodSplat(RegisterTile.WorldPositionServer); string their = null; if (player != null) { their = player.CharacterSettings?.TheirPronoun(player.Script); } if (their == null) { their = "their"; } Chat.AddLocalMsgToChat($"<b>{player.Name}</b> seizes up and falls limp, {their} eyes dead and lifeless...", gameObject); } TriggerEventMessage.SendTo(gameObject, Event.PlayerDied); } }
/// <summary> /// Send a Chat Msg from a player to the selected Chat Channels /// Server only /// </summary> public static void AddChatMsgToChat(ConnectedPlayer sentByPlayer, string message, ChatChannel channels) { message = AutoMod.ProcessChatServer(sentByPlayer, message); if (string.IsNullOrWhiteSpace(message)) { return; } var player = sentByPlayer.Script; // The exact words that leave the player's mouth (or that are narrated). Already includes HONKs, stutters, etc. // This step is skipped when speaking in the OOC channel. (string message, ChatModifier chatModifiers)processedMessage = (string.Empty, ChatModifier.None); // Placeholder values bool isOOC = channels.HasFlag(ChatChannel.OOC); if (!isOOC) { processedMessage = ProcessMessage(sentByPlayer, message); } var chatEvent = new ChatEvent { message = isOOC ? message : processedMessage.message, modifiers = (player == null) ? ChatModifier.None : processedMessage.chatModifiers, speaker = (player == null) ? sentByPlayer.Username : player.name, position = (player == null) ? TransformState.HiddenPos : player.gameObject.AssumedWorldPosServer(), channels = channels, originator = sentByPlayer.GameObject }; if (channels.HasFlag(ChatChannel.OOC)) { chatEvent.speaker = sentByPlayer.Username; var isAdmin = PlayerList.Instance.IsAdmin(sentByPlayer.UserId); if (isAdmin) { chatEvent.speaker = "[Admin] " + chatEvent.speaker; } if (Instance.OOCMute && !isAdmin) { return; } Instance.addChatLogServer.Invoke(chatEvent); //Sends OOC message to a discord webhook DiscordWebhookMessage.Instance.AddWebHookMessageToQueue(DiscordWebhookURLs.DiscordWebhookOOCURL, message, chatEvent.speaker, ServerData.ServerConfig.DiscordWebhookOOCMentionsID); if (!ServerData.ServerConfig.DiscordWebhookSendOOCToAllChat) { return; } //Send it to All chat DiscordWebhookMessage.Instance.AddWebHookMessageToQueue(DiscordWebhookURLs.DiscordWebhookAllChatURL, $"[{ChatChannel.OOC}] {message}\n", chatEvent.speaker); return; } // TODO the following code uses player.playerHealth, but ConciousState would be more appropriate. // Check if the player is allowed to talk: if (player != null && player.playerHealth != null) { if (!player.IsDeadOrGhost && player.mind.IsMiming && !processedMessage.chatModifiers.HasFlag(ChatModifier.Emote)) { AddWarningMsgFromServer(sentByPlayer.GameObject, "You can't talk because you made a vow of silence."); return; } if (player.playerHealth.IsCrit || player.playerHealth.IsCardiacArrest) { if (!player.playerHealth.IsDead) { return; } else { chatEvent.channels = ChatChannel.Ghost; } } else if (!player.playerHealth.IsDead && !player.IsGhost) { //Control the chat bubble player.playerNetworkActions.CmdToggleChatIcon(true, processedMessage.message, channels, processedMessage.chatModifiers); } } InvokeChatEvent(chatEvent); }
/// <summary> /// Send a Chat Msg from a player to the selected Chat Channels /// Server only /// </summary> public static void AddChatMsgToChat(ConnectedPlayer sentByPlayer, string message, ChatChannel channels, Loudness loudness = Loudness.NORMAL) { message = AutoMod.ProcessChatServer(sentByPlayer, message); if (string.IsNullOrWhiteSpace(message)) { return; } //Sanity check for null username if (string.IsNullOrWhiteSpace(sentByPlayer.Username)) { Logger.Log($"Null/empty Username, Details: Username: {sentByPlayer.Username}, ClientID: {sentByPlayer.ClientId}, IP: {sentByPlayer.Connection.address}", Category.Admin); return; } var player = sentByPlayer.Script; //Check to see whether this player is allowed to send on the chosen channels if (player != null) { channels &= player.GetAvailableChannelsMask(true); } else { //If player is null, must be in lobby therefore lock to OOC channels = ChatChannel.OOC; } if (channels == ChatChannel.None) { return; } // The exact words that leave the player's mouth (or that are narrated). Already includes HONKs, stutters, etc. // This step is skipped when speaking in the OOC channel. (string message, ChatModifier chatModifiers)processedMessage = (string.Empty, ChatModifier.None); // Placeholder values bool isOOC = channels.HasFlag(ChatChannel.OOC); if (!isOOC) { processedMessage = ProcessMessage(sentByPlayer, message); if (string.IsNullOrWhiteSpace(processedMessage.message)) { return; } } var chatEvent = new ChatEvent { message = isOOC ? message : processedMessage.message, modifiers = (player == null) ? ChatModifier.None : processedMessage.chatModifiers, speaker = (player == null) ? sentByPlayer.Username : player.playerName, position = (player == null) ? TransformState.HiddenPos : player.PlayerChatLocation.AssumedWorldPosServer(), channels = channels, originator = (player == null) ? sentByPlayer.GameObject : player.PlayerChatLocation, VoiceLevel = loudness }; //This is to make sure OOC doesn't break if (sentByPlayer.Job != JobType.NULL) { CheckVoiceLevel(sentByPlayer.Script, chatEvent.channels); } if (channels.HasFlag(ChatChannel.OOC)) { chatEvent.speaker = StripAll(sentByPlayer.Username); var isAdmin = PlayerList.Instance.IsAdmin(sentByPlayer.UserId); if (isAdmin) { chatEvent.speaker = "<color=red>[A]</color> " + chatEvent.speaker; } else if (PlayerList.Instance.IsMentor(sentByPlayer.UserId)) { chatEvent.speaker = "<color=#6400ff>[M]</color> " + chatEvent.speaker; } if (Instance.OOCMute && !isAdmin) { return; } //http/https links in OOC chat if (isAdmin || !GameManager.Instance.AdminOnlyHtml) { if (htmlRegex.IsMatch(chatEvent.message)) { var messageParts = chatEvent.message.Split(' '); var builder = new StringBuilder(); foreach (var part in messageParts) { if (!htmlRegex.IsMatch(part)) { builder.Append(part); builder.Append(" "); continue; } builder.Append($"<link={part}><color=blue>{part}</color></link> "); } chatEvent.message = builder.ToString(); //TODO have a config file available to whitelist/blacklist links if all players are allowed to post links //disables client side tag protection to allow <link=></link> tag chatEvent.stripTags = false; } } ChatRelay.Instance.PropagateChatToClients(chatEvent); var strippedSpeaker = StripTags(chatEvent.speaker); //Sends OOC message to a discord webhook DiscordWebhookMessage.Instance.AddWebHookMessageToQueue(DiscordWebhookURLs.DiscordWebhookOOCURL, message, strippedSpeaker, ServerData.ServerConfig.DiscordWebhookOOCMentionsID); if (!ServerData.ServerConfig.DiscordWebhookSendOOCToAllChat) { return; } //Send it to All chat DiscordWebhookMessage.Instance.AddWebHookMessageToQueue(DiscordWebhookURLs.DiscordWebhookAllChatURL, $"[{ChatChannel.OOC}] {message}\n", strippedSpeaker); return; } // TODO the following code uses player.playerHealth, but ConciousState would be more appropriate. // Check if the player is allowed to talk: if (player != null) { if (player.playerHealth != null) { if (!player.IsDeadOrGhost && player.mind.IsMiming && !processedMessage.chatModifiers.HasFlag(ChatModifier.Emote)) { AddWarningMsgFromServer(sentByPlayer.GameObject, "You can't talk because you made a vow of silence."); return; } if (player.playerHealth.IsCrit) { if (!player.playerHealth.IsDead) { return; } else { chatEvent.channels = ChatChannel.Ghost; } } else if (!player.playerHealth.IsDead && !player.IsGhost) { //Control the chat bubble player.playerNetworkActions.ServerToggleChatIcon(true, processedMessage.message, channels, processedMessage.chatModifiers); } } } InvokeChatEvent(chatEvent); }
/// <summary> /// Send a Chat Msg from a player to the selected Chat Channels /// Server only /// </summary> public static void AddChatMsgToChat(ConnectedPlayer sentByPlayer, string message, ChatChannel channels) { message = AutoMod.ProcessChatServer(sentByPlayer, message); if (string.IsNullOrWhiteSpace(message)) { return; } var player = sentByPlayer.Script; // The exact words that leave the player's mouth (or that are narrated). Already includes HONKs, stutters, etc. // This step is skipped when speaking in the OOC channel. (string message, ChatModifier chatModifiers)processedMessage = (string.Empty, ChatModifier.None); // Placeholder values bool isOOC = channels.HasFlag(ChatChannel.OOC); if (!isOOC) { processedMessage = ProcessMessage(sentByPlayer, message); } var chatEvent = new ChatEvent { message = isOOC ? message : processedMessage.message, modifiers = (player == null) ? ChatModifier.None : processedMessage.chatModifiers, speaker = (player == null) ? sentByPlayer.Username : player.name, position = (player == null) ? TransformState.HiddenPos : player.gameObject.AssumedWorldPosServer(), channels = channels, originator = sentByPlayer.GameObject }; if (channels.HasFlag(ChatChannel.OOC)) { chatEvent.speaker = sentByPlayer.Username; var isAdmin = PlayerList.Instance.IsAdmin(sentByPlayer.UserId); if (isAdmin) { chatEvent.speaker = "<color=red>[Admin]</color> " + chatEvent.speaker; } else if (PlayerList.Instance.IsMentor(sentByPlayer.UserId)) { chatEvent.speaker = "<color=#6400ff>[Mentor]</color> " + chatEvent.speaker; } if (Instance.OOCMute && !isAdmin) { return; } //http/https links in OOC chat if (isAdmin || !GameManager.Instance.AdminOnlyHtml) { if (htmlRegex.IsMatch(chatEvent.message)) { var messageParts = chatEvent.message.Split(' '); var builder = new StringBuilder(); foreach (var part in messageParts) { if (!htmlRegex.IsMatch(part)) { builder.Append(part); builder.Append(" "); continue; } builder.Append($"<link={part}><color=blue>{part}</color></link> "); } chatEvent.message = builder.ToString(); //TODO have a config file available to whitelist/blacklist links if all players are allowed to post links //disables client side tag protection to allow <link=></link> tag chatEvent.stripTags = false; } } Instance.addChatLogServer.Invoke(chatEvent); //Sends OOC message to a discord webhook DiscordWebhookMessage.Instance.AddWebHookMessageToQueue(DiscordWebhookURLs.DiscordWebhookOOCURL, message, chatEvent.speaker, ServerData.ServerConfig.DiscordWebhookOOCMentionsID); if (!ServerData.ServerConfig.DiscordWebhookSendOOCToAllChat) { return; } //Send it to All chat DiscordWebhookMessage.Instance.AddWebHookMessageToQueue(DiscordWebhookURLs.DiscordWebhookAllChatURL, $"[{ChatChannel.OOC}] {message}\n", chatEvent.speaker); return; } // TODO the following code uses player.playerHealth, but ConciousState would be more appropriate. // Check if the player is allowed to talk: if (player != null && player.playerHealth != null) { if (!player.IsDeadOrGhost && player.mind.IsMiming && !processedMessage.chatModifiers.HasFlag(ChatModifier.Emote)) { AddWarningMsgFromServer(sentByPlayer.GameObject, "You can't talk because you made a vow of silence."); return; } if (player.playerHealth.IsCrit || player.playerHealth.IsCardiacArrest) { if (!player.playerHealth.IsDead) { return; } else { chatEvent.channels = ChatChannel.Ghost; } } else if (!player.playerHealth.IsDead && !player.IsGhost) { //Control the chat bubble player.playerNetworkActions.CmdToggleChatIcon(true, processedMessage.message, channels, processedMessage.chatModifiers); } } InvokeChatEvent(chatEvent); }