using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Alpha;
using Alpha.Core.Command;
using Alpha.Core.Util;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Fomo.Core;
using Fomo.Core.Commands;
using Fomo.Patches;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PurrNet;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("AndrewLin")]
[assembly: AssemblyConfiguration("Publish")]
[assembly: AssemblyDescription("FOMO: A mod for On-Together to expand chat size, log chats, and relay messages via WebSocket. Use /fomohelp")]
[assembly: AssemblyFileVersion("1.2.9.0")]
[assembly: AssemblyInformationalVersion("1.2.9+93bf6c254192ca3bde9494f062dab68782362cda")]
[assembly: AssemblyProduct("AndrewLin.Fomo")]
[assembly: AssemblyTitle("AndrewLin.Fomo")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/andrewlimforfun/ot-mods")]
[assembly: AssemblyVersion("1.2.9.0")]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace Fomo
{
public static class BuildInfo
{
public const string Version = "1.2.9";
}
[BepInPlugin("com.andrewlin.ontogether.fomo", "Fomo", "1.2.9")]
public class FomoPlugin : BaseUnityPlugin
{
public const int OriginalNotificationLimit = 99;
public const int DefaultNotificationLimit = 300;
public const int MaxNotificationLimit = 999;
public const int DefaultChatSinkLocalRange = 5;
public const int DefaultGlobalChatMessageLimit = 50;
public const int DefaultLocalChatMessageLimit = 25;
private static readonly ConcurrentQueue<Action> _mainThreadQueue = new ConcurrentQueue<Action>();
public const string ModGUID = "com.andrewlin.ontogether.fomo";
public const string ModName = "Fomo";
public const string ModVersion = "1.2.9";
public static ConfigEntry<bool>? EnableFeature { get; private set; }
public static ConfigEntry<bool>? ShowCommand { get; private set; }
public static ConfigEntry<bool>? CleanChatSinkTags { get; private set; }
public static ConfigEntry<int>? GlobalMessageLimitCount { get; private set; }
public static ConfigEntry<int>? LocalMessageLimitCount { get; private set; }
public static ConfigEntry<int>? ChatSinkLocalRange { get; private set; }
public static ConfigEntry<bool>? DispatchIncomingLocal { get; private set; }
public static ChatSinkManager? SinkManager { get; private set; }
public static void RunOnMainThread(Action action)
{
_mainThreadQueue.Enqueue(action);
}
public static void DispatchIncomingText(string text)
{
string text2 = text;
if (string.IsNullOrWhiteSpace(text2))
{
return;
}
text2 = text2.Trim();
if (AlphaPlugin.CommandManager != null && text2.StartsWith("/") && text2.Length > 2)
{
RunOnMainThread(delegate
{
ChatCommandManager commandManager = AlphaPlugin.CommandManager;
string text3 = text2.Split(' ')[0];
string text4 = text3.Substring(1, text3.Length - 1).ToLower();
if (string.IsNullOrWhiteSpace(text4) || !commandManager.ContainsCommand(text4) || !commandManager.ProcessInput(text2))
{
ChatUtils.UISendMessage(text2);
}
});
}
else
{
string userName = PlayerUtils.GetUserName();
bool flag = DispatchIncomingLocal?.Value ?? false;
ChatUtils.SendMessageAsync(userName, text2, flag, "word", (Vector3?)null);
}
}
private void Awake()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
((BaseUnityPlugin)this).Logger.LogInfo((object)"Fomo v1.2.9 is loaded!");
InitConfig();
Harmony val = new Harmony("com.andrewlin.ontogether.fomo");
val.PatchAll(typeof(TextChannelManagerPatch));
val.PatchAll(typeof(GameSettingsPatch));
val.PatchAll(typeof(MainSceneManagerPatch));
val.PatchAll(typeof(PlayerCustomizationControllerPatch));
ChatCommandManager commandManager = AlphaPlugin.CommandManager;
if (commandManager != null)
{
commandManager.Register((IChatCommand)(object)new FomoChatLocalCommand());
}
ChatCommandManager commandManager2 = AlphaPlugin.CommandManager;
if (commandManager2 != null)
{
commandManager2.Register((IChatCommand)(object)new FomoChatGlobalCommand());
}
ChatCommandManager commandManager3 = AlphaPlugin.CommandManager;
if (commandManager3 != null)
{
commandManager3.Register((IChatCommand)(object)new FomoChatSinkCleanTagsCommand());
}
ChatCommandManager commandManager4 = AlphaPlugin.CommandManager;
if (commandManager4 != null)
{
commandManager4.Register((IChatCommand)(object)new FomoChatSinkLocalRangeCommand());
}
ChatCommandManager commandManager5 = AlphaPlugin.CommandManager;
if (commandManager5 != null)
{
commandManager5.Register((IChatCommand)(object)new FomoIncomingModeCommand());
}
ChatCommandManager commandManager6 = AlphaPlugin.CommandManager;
if (commandManager6 != null)
{
commandManager6.Register((IChatCommand)(object)new FomoMessageLimitCommand());
}
ChatCommandManager commandManager7 = AlphaPlugin.CommandManager;
if (commandManager7 != null)
{
commandManager7.Register((IChatCommand)(object)new FomoToggleCommand());
}
SinkManager = new ChatSinkManager();
}
private void InitConfig()
{
EnableFeature = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableFeature", true, "Enable or disable the mod feature.");
ShowCommand = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowCommand", false, "Show the command in chat when used.");
CleanChatSinkTags = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "CleanChatSinkTags", false, "Strip TMP color/formatting tags (e.g. <#ff0000>) from chat messages before dispatching to sinks (affects all sinks).");
GlobalMessageLimitCount = ((BaseUnityPlugin)this).Config.Bind<int>("Chat", "GlobalMessageLimitCount", 50, "Max number of messages shown in the global chat window. Game default is 50.");
LocalMessageLimitCount = ((BaseUnityPlugin)this).Config.Bind<int>("Chat", "LocalMessageLimitCount", 25, "Max number of messages shown in the local chat window. Game default is 25.");
ChatSinkLocalRange = ((BaseUnityPlugin)this).Config.Bind<int>("Chat", "ChatLogLocalRange", 5, "Local range for chat log messages.");
DispatchIncomingLocal = ((BaseUnityPlugin)this).Config.Bind<bool>("Chat", "DispatchIncomingLocal", false, "When true, messages from external sources (Telegram, WebSocket, etc.) are dispatched as local chat instead of global.");
}
private void Update()
{
Action result;
while (_mainThreadQueue.TryDequeue(out result))
{
try
{
result();
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Main thread action failed: " + ex.Message));
}
}
}
private void OnDestroy()
{
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "AndrewLin.Fomo";
public const string PLUGIN_NAME = "AndrewLin.Fomo";
public const string PLUGIN_VERSION = "1.2.9";
}
}
namespace Fomo.Patches
{
[HarmonyPatch(typeof(GameSettings))]
public class GameSettingsPatch
{
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
[HarmonyPostfix]
public static void GlobalMessageLimitCountPostfix(ref int __result)
{
int num = FomoPlugin.GlobalMessageLimitCount?.Value ?? __result;
if (num > 0)
{
__result = num;
}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
[HarmonyPostfix]
public static void LocalMessageLimitCountPostfix(ref int __result)
{
int num = FomoPlugin.LocalMessageLimitCount?.Value ?? __result;
if (num > 0)
{
__result = num;
}
}
}
[HarmonyPatch(typeof(MainSceneManager))]
internal class MainSceneManagerPatch
{
private static readonly ManualLogSource _log = Logger.CreateLogSource("Fomo.MSMP");
[HarmonyPatch("ConnectionLost")]
[HarmonyPostfix]
public static void ConnectionLostPostfix(NotificationStatus notificationStatus)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
_log.LogWarning((object)$"Disconnected: {notificationStatus} at {DateTime.Now}");
ChatEntry entry = new ChatEntry(DateTime.Now, $"Disconnected: {notificationStatus}");
if (FomoPlugin.SinkManager != null)
{
FomoPlugin.SinkManager.BroadcastAsync(entry);
}
}
[HarmonyPatch("ReturnMenu", new Type[] { typeof(bool) })]
[HarmonyPostfix]
public static void ReturnMenuPostfix(bool wishListCheck)
{
_log.LogInfo((object)$"Returned to menu at {DateTime.Now}");
ChatEntry entry = new ChatEntry(DateTime.Now, "Returned to menu");
if (FomoPlugin.SinkManager != null)
{
FomoPlugin.SinkManager.BroadcastAsync(entry);
}
}
}
[HarmonyPatch(typeof(PlayerCustomizationController))]
public static class PlayerCustomizationControllerPatch
{
private static readonly ManualLogSource _log = Logger.CreateLogSource("Fomo.PCCP");
[HarmonyPostfix]
[HarmonyPatch("UpdateOnNewPeopleJoin_Original_0")]
public static void UpdateOnNewPeopleJoin_Original_0_Postfix(string playerSteamID, PlayerIDInfo playerIDInfo)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
string @string = Encoding.Unicode.GetString(playerIDInfo.Name);
NetworkSingleton<TextChannelManager>.I.AddNotification(@string + " - " + playerSteamID);
}
}
[HarmonyPatch(typeof(TextChannelManager))]
public class TextChannelManagerPatch
{
private const int _selfDistance = 0;
[HarmonyPatch("AddNotification", new Type[] { typeof(string) })]
[HarmonyPostfix]
public static void AddNotificationPostfix(string text)
{
string text2 = text;
ConfigEntry<bool>? enableFeature = FomoPlugin.EnableFeature;
if (enableFeature == null || enableFeature.Value)
{
Task.Run(async delegate
{
ChatEntry entry = new ChatEntry(message: ChatUtils.CleanTMPTags(text2), timestamp: DateTime.Now, channel: null, userName: null, source: "AN");
await (FomoPlugin.SinkManager?.BroadcastAsync(entry) ?? Task.CompletedTask);
});
}
}
[HarmonyPatch("SendMessageAsync", new Type[]
{
typeof(byte[]),
typeof(byte[]),
typeof(bool),
typeof(Vector3),
typeof(string),
typeof(RPCInfo)
})]
[HarmonyPostfix]
public static void SendMessageAsyncPostfix(byte[] textBytes, byte[] userName, bool isLocal, Vector3 pos, string playerID, RPCInfo info = default(RPCInfo))
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
byte[] userName2 = userName;
byte[] textBytes2 = textBytes;
string playerID2 = playerID;
ConfigEntry<bool>? enableFeature = FomoPlugin.EnableFeature;
if (enableFeature == null || enableFeature.Value)
{
Task.Run(async delegate
{
string channel = (isLocal ? "Local" : "Global");
string cleanUserName = ChatUtils.CleanTMPTags(Encoding.Unicode.GetString(userName2));
string rawMessage = Encoding.Unicode.GetString(textBytes2);
ChatEntry entry = new ChatEntry(message: (FomoPlugin.CleanChatSinkTags?.Value ?? false) ? ChatUtils.CleanTMPTags(rawMessage) : rawMessage, timestamp: DateTime.Now, channel: channel, userName: cleanUserName, source: "SM", playerID: playerID2, distance: isLocal ? ((int)Vector3.Distance(pos, NetworkSingleton<TextChannelManager>.I.MainPlayer.position)) : 0);
await (FomoPlugin.SinkManager?.BroadcastAsync(entry) ?? Task.CompletedTask);
});
}
}
[HarmonyPatch("OnChannelMessageReceived", new Type[]
{
typeof(string),
typeof(string),
typeof(Vector3),
typeof(bool),
typeof(int),
typeof(string)
})]
[HarmonyPostfix]
public static void OnChannelMessageReceivedPostfix(string userName, string message, Vector3 senderPosition, bool isLocal, int senderIndex, string playerID)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
string userName2 = userName;
string message2 = message;
string playerID2 = playerID;
ConfigEntry<bool>? enableFeature = FomoPlugin.EnableFeature;
if ((enableFeature != null && !enableFeature.Value) || MonoSingleton<DataManager>.I.BanData.IgnorePlayers.Contains(playerID2) || MonoSingleton<DataManager>.I.BanData.MutedPlayers.Contains(playerID2) || SteamUtils.GetPlayerSteamID() == playerID2)
{
return;
}
Task.Run(async delegate
{
string channel = (isLocal ? "Local" : "Global");
int? distance = (int)Vector3.Distance(senderPosition, NetworkSingleton<TextChannelManager>.I.MainPlayer.position);
int localRange = FomoPlugin.ChatSinkLocalRange?.Value ?? 5;
if (!isLocal || !(distance > localRange))
{
ChatEntry entry = new ChatEntry(userName: ChatUtils.CleanTMPTags(userName2), message: (FomoPlugin.CleanChatSinkTags?.Value ?? false) ? ChatUtils.CleanTMPTags(message2) : message2, timestamp: DateTime.Now, channel: channel, source: "OC", playerID: playerID2, distance: distance);
await (FomoPlugin.SinkManager?.BroadcastAsync(entry) ?? Task.CompletedTask);
}
});
}
}
}
namespace Fomo.Core
{
public class ChatEntry
{
public DateTime Timestamp { get; }
public string Message { get; }
public string? Channel { get; }
public string? UserName { get; }
public string? Source { get; }
public string? PlayerID { get; }
public int? Distance { get; }
public bool IsNotification => Channel == null || UserName == null;
public ChatEntry(DateTime timestamp, string message, string? channel = null, string? userName = null, string? source = null, string? playerID = null, int? distance = null)
{
Timestamp = timestamp;
Message = message;
Channel = channel;
UserName = userName;
Source = source;
PlayerID = playerID;
Distance = distance;
}
}
public static class ChatEntryFormatter
{
public const string DefaultMessageFormat = "[{timestamp:HH:mm}] [{channel:short}{distance}] {username}: {message}";
public const string DefaultNotificationFormat = "[{timestamp:HH:mm}] {message}";
public const string PlaceholdersCsv = "{timestamp[:fmt]}, {channel[:short]}, {username}, {message}, {distance}, {source}, {playerid}";
private static readonly Regex TokenRegex = new Regex("\\{(\\w+)(?::([^}]*))?\\}", RegexOptions.Compiled);
public static string Format(ChatEntry entry, string? format = null)
{
ChatEntry entry2 = entry;
string text = (entry2.IsNotification ? "[{timestamp:HH:mm}] {message}" : "[{timestamp:HH:mm}] [{channel:short}{distance}] {username}: {message}");
string input = (string.IsNullOrEmpty(format) ? text : format);
return TokenRegex.Replace(input, delegate(Match m)
{
string value = m.Groups[1].Value;
string text2 = (m.Groups[2].Success ? m.Groups[2].Value : string.Empty);
return value switch
{
"timestamp" => entry2.Timestamp.ToString(string.IsNullOrEmpty(text2) ? "HH:mm" : text2),
"channel" => FormatChannelLabel(entry2, text2),
"username" => entry2.UserName ?? string.Empty,
"source" => entry2.Source ?? string.Empty,
"playerid" => FormatPlayerID(entry2, text2),
"message" => entry2.Message,
"distance" => FormatDistanceLabel(entry2, text2),
_ => m.Value,
};
});
}
private static string FormatPlayerID(ChatEntry entry, string specifier)
{
if (entry.PlayerID != null && entry.PlayerID.Length >= 3)
{
if (specifier == "")
{
return entry.PlayerID;
}
if (specifier == "short")
{
string? playerID = entry.PlayerID;
int length = playerID.Length;
int num = length - 3;
return playerID.Substring(num, length - num);
}
if (int.TryParse(specifier, out var result) && result > 0 && result <= entry.PlayerID.Length)
{
return entry.PlayerID.Substring(entry.PlayerID.Length - result);
}
return entry.PlayerID;
}
return string.Empty;
}
public static string FormatDistanceLabel(ChatEntry entry, string specifier)
{
if (entry.Distance.HasValue && entry.Distance.Value > 0)
{
return $"{entry.Distance.Value}";
}
return string.Empty;
}
public static string FormatChannelLabel(ChatEntry entry, string specifier = "")
{
string text = entry.Channel ?? "System";
if (specifier == "short")
{
text = ((text.Length > 0) ? text.Substring(0, 1) : "?");
}
return text;
}
}
public class ChatSinkManager
{
private readonly ManualLogSource _log = Logger.CreateLogSource("Fomo.CSM");
private readonly List<IChatSink> _sinks = new List<IChatSink>();
public void Register(IChatSink sink)
{
_sinks.Add(sink);
_log.LogInfo((object)("Registered chat sink: " + sink.GetType().Name));
}
public async Task BroadcastAsync(ChatEntry entry)
{
foreach (IChatSink sink in _sinks)
{
try
{
await sink.SendAsync(entry);
}
catch (Exception ex)
{
_log.LogWarning((object)("[" + sink.GetType().Name + "] Unhandled error: " + ex.Message));
}
}
}
}
public interface IChatSink
{
Task SendAsync(ChatEntry entry);
}
}
namespace Fomo.Core.Commands
{
public class FomoChatGlobalCommand : IChatCommand, IComparable<IChatCommand>
{
public const string CMD = "fomochatglobal";
public string Name => "fomochatglobal";
public string ShortName => "fcg";
public string Description => "Send message in global chat. ";
public string Namespace => "fomo";
public void Execute(string[] args)
{
if (args.Length < 1)
{
ChatUtils.AddGlobalNotification("Usage: /fomochatglobal [message]");
return;
}
string text = string.Join(" ", args);
if (string.IsNullOrWhiteSpace(text))
{
ChatUtils.AddGlobalNotification("Please enter a valid message.");
return;
}
string userName = PlayerUtils.GetUserName();
ChatUtils.SendMessageAsync(userName, text, false, "word", (Vector3?)null);
}
}
public class FomoChatLocalCommand : IChatCommand, IComparable<IChatCommand>
{
public const string CMD = "fomochatlocal";
public string Name => "fomochatlocal";
public string ShortName => "fcl";
public string Description => "Send message in local chat. ";
public string Namespace => "fomo";
public void Execute(string[] args)
{
if (args.Length < 1)
{
ChatUtils.AddGlobalNotification("Usage: /fomochatlocal [message]");
return;
}
string text = string.Join(" ", args);
if (string.IsNullOrWhiteSpace(text))
{
ChatUtils.AddGlobalNotification("Please enter a valid message.");
return;
}
string userName = PlayerUtils.GetUserName();
ChatUtils.SendMessageAsync(userName, text, true, "word", (Vector3?)null);
}
}
public class FomoChatSinkCleanTagsCommand : IChatCommand, IComparable<IChatCommand>
{
public const string CMD = "fomochatsinkcleantags";
public string Name => "fomochatsinkcleantags";
public string ShortName => "fcsct";
public string Description
{
get
{
ConfigEntry<bool>? cleanChatSinkTags = FomoPlugin.CleanChatSinkTags;
return "Toggle cleaning TMP tags in the chat sink e.g. <noparse><#ff0000></noparse>. Currently: " + ((cleanChatSinkTags != null && cleanChatSinkTags.Value) ? "enabled" : "disabled") + ". Usage: /fomocleanchatsinktags";
}
}
public string Namespace => "fomo";
public void Execute(string[] args)
{
if (FomoPlugin.CleanChatSinkTags != null)
{
FomoPlugin.CleanChatSinkTags.Value = !FomoPlugin.CleanChatSinkTags.Value;
ChatUtils.AddGlobalNotification("Cleaning TMP tags in chat sink is now " + (FomoPlugin.CleanChatSinkTags.Value ? "enabled" : "disabled") + ".");
}
}
}
public class FomoChatSinkLocalRangeCommand : IChatCommand, IComparable<IChatCommand>
{
public const string CMD = "fomochatsinklocalrange";
public string Name => "fomochatsinklocalrange";
public string ShortName => "fcslr";
public string Description => "Get or set the local range for the chat sink. No args = get current value. Pass a number to set it. " + $"Current: {FomoPlugin.ChatSinkLocalRange?.Value ?? 5}";
public bool IsHidden => true;
public string Namespace => "fomo";
public void Execute(string[] args)
{
if (FomoPlugin.ChatSinkLocalRange == null)
{
ChatUtils.AddGlobalNotification("Chat sink local range config is not initialized yet.");
return;
}
if (args.Length == 0)
{
ChatUtils.AddGlobalNotification($"Chat sink local range is currently set to {FomoPlugin.ChatSinkLocalRange.Value}.");
return;
}
if (!int.TryParse(args[0], out var result) || result <= 0)
{
ChatUtils.AddGlobalNotification("Please enter a valid positive integer.");
return;
}
FomoPlugin.ChatSinkLocalRange.Value = result;
ChatUtils.AddGlobalNotification($"Chat sink local range is now set to {result}.");
}
}
public class FomoIncomingModeCommand : IChatCommand, IComparable<IChatCommand>
{
public const string CMD = "fomoincomingmode";
public string Name => "fomoincomingmode";
public string ShortName => "fim";
public string Description
{
get
{
ConfigEntry<bool>? dispatchIncomingLocal = FomoPlugin.DispatchIncomingLocal;
return "Toggle incoming message channel between global and local. Current: " + ((dispatchIncomingLocal != null && dispatchIncomingLocal.Value) ? "local" : "global") + ". Usage: /fomoincomingmode [global|local]";
}
}
public string Namespace => "fomo";
public void Execute(string[] args)
{
if (FomoPlugin.DispatchIncomingLocal == null)
{
return;
}
if (args.Length == 0)
{
FomoPlugin.DispatchIncomingLocal.Value = !FomoPlugin.DispatchIncomingLocal.Value;
}
else
{
string text = args[0].ToLower();
if (text == "local")
{
FomoPlugin.DispatchIncomingLocal.Value = true;
}
else
{
if (!(text == "global"))
{
ChatUtils.AddGlobalNotification("Unknown mode '" + args[0] + "'. Use 'global' or 'local'.");
return;
}
FomoPlugin.DispatchIncomingLocal.Value = false;
}
}
string text2 = (FomoPlugin.DispatchIncomingLocal.Value ? "local" : "global");
ChatUtils.AddGlobalNotification("Incoming messages will now be sent to " + text2 + " chat.");
}
}
public class FomoMessageLimitCommand : IChatCommand, IComparable<IChatCommand>
{
public const string CMD = "fomomessagelimit";
public string Name => "fomomessagelimit";
public string ShortName => "fml";
public string Description => "Set the global or local chat message window size. Usage: /fomomessagelimit [global|local] [number]. " + $"Current: global={FomoPlugin.GlobalMessageLimitCount?.Value}, local={FomoPlugin.LocalMessageLimitCount?.Value}";
public string Namespace => "fomo";
public void Execute(string[] args)
{
if (FomoPlugin.GlobalMessageLimitCount == null || FomoPlugin.LocalMessageLimitCount == null)
{
return;
}
if (args.Length != 2)
{
ChatUtils.AddGlobalNotification("Usage: /fomomessagelimit [global|local] [number]");
return;
}
string text = args[0].ToLower();
if (!int.TryParse(args[1], out var result) || result <= 0)
{
ChatUtils.AddGlobalNotification("Invalid number. Please enter a positive integer.");
}
else if (text == "global")
{
FomoPlugin.GlobalMessageLimitCount.Value = result;
ChatUtils.AddGlobalNotification($"Global message limit set to {result}.");
}
else if (text == "local")
{
FomoPlugin.LocalMessageLimitCount.Value = result;
ChatUtils.AddGlobalNotification($"Local message limit set to {result}.");
}
else
{
ChatUtils.AddGlobalNotification("Unknown type '" + text + "'. Use 'global' or 'local'.");
}
}
}
public class FomoToggleCommand : IChatCommand, IComparable<IChatCommand>
{
public const string CMD = "fomotoggle";
public string Name => "fomotoggle";
public string ShortName => "ft";
public string Description => "Toggle Fomo feature on/off. ";
public string Namespace => "fomo";
public void Execute(string[] args)
{
if (FomoPlugin.EnableFeature != null)
{
FomoPlugin.EnableFeature.Value = !FomoPlugin.EnableFeature.Value;
ChatUtils.AddGlobalNotification("Fomo feature is now " + (FomoPlugin.EnableFeature.Value ? "enabled" : "disabled") + ".");
}
}
}
}