fix vent time & add Admins.txt

This commit is contained in:
Gurge44 committed 2025-07-24 19:43:08 +02:00
1 parent f60462f669
commit 55bca0d87c
40 files changed
+197 -63

No files matched your search

+4 -1
View File
@@ -751,6 +751,7 @@ public static class Options
public static OptionItem ApplyBanList;
public static OptionItem ApplyModeratorList;
public static OptionItem ApplyVIPList;
public static OptionItem ApplyAdminList;
public static OptionItem AutoWarnStopWords;
public static OptionItem DIYGameSettings;
@@ -1007,7 +1008,8 @@ public static class Options
Command.UsageLevels.Everyone => ":purple_circle: Everyone",
Command.UsageLevels.Modded => ":green_circle: Modded Clients",
Command.UsageLevels.Host => ":yellow_circle: Host",
Command.UsageLevels.HostOrModerator => ":red_circle: Host And Moderators",
Command.UsageLevels.HostOrModerator => ":red_circle: Host, Moderators, And Admins",
Command.UsageLevels.HostOrAdmin => ":white_circle: Host And Admins",
_ => string.Empty
};
@@ -1534,6 +1536,7 @@ public static class Options
ApplyBanList = new BooleanOptionItem(19304, "ApplyBanList", true, TabGroup.SystemSettings, true);
ApplyModeratorList = new BooleanOptionItem(19305, "ApplyModeratorList", true, TabGroup.SystemSettings);
ApplyVIPList = new BooleanOptionItem(19306, "ApplyVIPList", true, TabGroup.SystemSettings);
ApplyAdminList = new BooleanOptionItem(19330, "ApplyAdminList", true, TabGroup.SystemSettings);
LoadingPercentage = 61;
+2
View File
@@ -671,8 +671,10 @@ internal static class RPCHandlerPatch
PlayerControl player = reader.ReadByte().GetPlayer();
string text = reader.ReadString();
bool modCommand = reader.ReadBoolean();
bool adminCommand = reader.ReadBoolean();
if (modCommand && !ChatCommands.IsPlayerModerator(player.FriendCode)) break;
if (adminCommand && !ChatCommands.IsPlayerAdmin(player.FriendCode)) break;
const BindingFlags flags = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
typeof(ChatCommands).GetMethod(methodName, flags)?.Invoke(null, [player, text, text.Split(' ')]);
+8 -3
View File
@@ -73,7 +73,13 @@ Symbols Emoji: ™ 〰 🆗 🆕 🆙 🆒 🆓 🆖 🅿 Ⓜ 🆑 🆘 🆚 ⚠
public static class Utils
{
public const string EmptyMessage = "<size=0>.</size>";
private static readonly DateTime TimeStampStartTime = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
private static readonly DateTime Epoch = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
private static readonly DateTime StartTime = DateTime.UtcNow;
private static readonly long EpochStartSeconds = (long)(StartTime - Epoch).TotalSeconds;
private static readonly Stopwatch Stopwatch = Stopwatch.StartNew();
public static long TimeStamp => EpochStartSeconds + (long)Stopwatch.Elapsed.TotalSeconds;
private static readonly StringBuilder SelfSuffix = new();
private static readonly StringBuilder SelfMark = new(20);
@@ -88,7 +94,6 @@ public static class Utils
private static readonly Dictionary<byte, (string Text, int Duration, bool Long)> LongRoleDescriptions = [];
public static long TimeStamp => (long)(DateTime.Now.ToUniversalTime() - TimeStampStartTime).TotalSeconds;
public static bool DoRPC => AmongUsClient.Instance.AmHost && Main.AllPlayerControls.Any(x => x.IsModdedClient() && !x.IsHost());
public static int TotalTaskCount => Main.RealOptionsData.GetInt(Int32OptionNames.NumCommonTasks) + Main.RealOptionsData.GetInt(Int32OptionNames.NumLongTasks) + Main.RealOptionsData.GetInt(Int32OptionNames.NumShortTasks);
private static int AllPlayersCount => Main.PlayerStates.Values.Count(state => state.countTypes != CountTypes.OutOfGame);
@@ -97,7 +102,7 @@ public static class Utils
public static long GetTimeStamp(DateTime? dateTime = null)
{
return (long)((dateTime ?? DateTime.Now).ToUniversalTime() - TimeStampStartTime).TotalSeconds;
return (long)((dateTime ?? DateTime.Now).ToUniversalTime() - Epoch).TotalSeconds;
}
public static void ErrorEnd(string text)
+109 -10
View File
@@ -28,7 +28,8 @@ internal class Command(string[] commandForms, string arguments, string descripti
Everyone,
Modded,
Host,
HostOrModerator
HostOrModerator,
HostOrAdmin
}
public enum UsageTimes
@@ -70,6 +71,7 @@ internal class Command(string[] commandForms, string arguments, string descripti
case UsageLevels.Host when !pc.IsHost():
case UsageLevels.Modded when !pc.IsModdedClient():
case UsageLevels.HostOrModerator when !pc.IsHost() && (AmongUsClient.Instance.AmHost && !ChatCommands.IsPlayerModerator(pc.FriendCode)):
case UsageLevels.HostOrAdmin when !pc.IsHost() && AmongUsClient.Instance.AmHost && !ChatCommands.IsPlayerAdmin(pc.FriendCode):
if (sendErrorMessage) Utils.SendMessage("\n", pc.PlayerId, GetString($"Commands.NoAccess.Level.{UsageLevel}"));
return false;
}
@@ -159,12 +161,12 @@ internal static class ChatCommands
new(["chat", "сообщение", "腹语者发送消息"], "{message}", GetString("CommandDescription.Chat"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, ChatCommand, true, true, [GetString("CommandArgs.Chat.Message")]),
new(["check", "проверить", "检查", "veificar"], "{id} {role}", GetString("CommandDescription.Check"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, CheckCommand, true, true, [GetString("CommandArgs.Check.Id"), GetString("CommandArgs.Check.Role")]),
new(["ban", "kick", "бан", "кик", "забанить", "кикнуть", "封禁", "踢出", "banir", "expulsar"], "{id}", GetString("CommandDescription.Ban"), Command.UsageLevels.HostOrModerator, Command.UsageTimes.Always, BanKickCommand, true, false, [GetString("CommandArgs.Ban.Id")]),
new(["exe", "выкинуть", "驱逐", "executar"], "{id}", GetString("CommandDescription.Exe"), Command.UsageLevels.Host, Command.UsageTimes.Always, ExeCommand, true, false, [GetString("CommandArgs.Exe.Id")]),
new(["exe", "выкинуть", "驱逐", "executar"], "{id}", GetString("CommandDescription.Exe"), Command.UsageLevels.HostOrAdmin, Command.UsageTimes.Always, ExeCommand, true, false, [GetString("CommandArgs.Exe.Id")]),
new(["kill", "убить", "击杀", "matar"], "{id}", GetString("CommandDescription.Kill"), Command.UsageLevels.Host, Command.UsageTimes.Always, KillCommand, true, false, [GetString("CommandArgs.Kill.Id")]),
new(["colour", "color", "цвет", "更改颜色", "cor"], "{color}", GetString("CommandDescription.Colour"), Command.UsageLevels.Everyone, Command.UsageTimes.InLobby, ColorCommand, true, false, [GetString("CommandArgs.Colour.Color")]),
new(["id", "guesslist", "айди", "ID列表"], "", GetString("CommandDescription.ID"), Command.UsageLevels.Everyone, Command.UsageTimes.Always, IDCommand, true, false),
new(["changerole", "изменитьроль", "измроль", "修改职业", "mudar-função"], "{role}", GetString("CommandDescription.ChangeRole"), Command.UsageLevels.Host, Command.UsageTimes.InGame, ChangeRoleCommand, true, false, [GetString("CommandArgs.ChangeRole.Role")]),
new(["end", "закончить", "завершить", "结束游戏", "encerrar", "finalizar", "fim"], "", GetString("CommandDescription.End"), Command.UsageLevels.Host, Command.UsageTimes.InGame, EndCommand, true, false),
new(["end", "закончить", "завершить", "结束游戏", "encerrar", "finalizar", "fim"], "", GetString("CommandDescription.End"), Command.UsageLevels.HostOrAdmin, Command.UsageTimes.InGame, EndCommand, true, false),
new(["cosid", "костюм", "одежда", "服装ID"], "", GetString("CommandDescription.CosID"), Command.UsageLevels.Modded, Command.UsageTimes.Always, CosIDCommand, true, false),
new(["mt", "hy", "собрание", "开会/结束会议"], "", GetString("CommandDescription.MTHY"), Command.UsageLevels.Host, Command.UsageTimes.InGame, MTHYCommand, true, false),
new(["csd", "кзвук", "自定义播放声音"], "{sound}", GetString("CommandDescription.CSD"), Command.UsageLevels.Modded, Command.UsageTimes.Always, CSDCommand, true, false, [GetString("CommandArgs.CSD.Sound")]),
@@ -208,6 +210,8 @@ internal static class ChatCommands
new(["forge"], "{id} {role}", GetString("CommandDescription.Forge"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, ForgeCommand, true, true, [GetString("CommandArgs.Forge.Id"), GetString("CommandArgs.Forge.Role")]),
new(["choose", "pick", "выбрать", "选择", "escolher"], "{role}", GetString("CommandDescription.Choose"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, ChooseCommand, true, true, [GetString("CommandArgs.Choose.Role")]),
new(["copypreset", "presetcopy", "скопироватьсохранение", "скопироватьсохр", "复制预设", "copiar"], "{sourcepreset} {targetpreset}", GetString("CommandDescription.CopyPreset"), Command.UsageLevels.Host, Command.UsageTimes.InLobby, CopyPresetCommand, true, false, [GetString("CommandArgs.CopyPreset.SourcePreset"), GetString("CommandArgs.CopyPreset.TargetPreset")]),
new(["addadmin", "добавитьадмин", "добадмин", "指定管理员", "admin-add"], "{id}", GetString("CommandDescription.AddAdmin"), Command.UsageLevels.Host, Command.UsageTimes.Always, AddAdminCommand, true, false, [GetString("CommandArgs.AddAdmin.Id")]),
new(["deleteadmin", "удалитьадмин", "убратьадмин", "удалитьадминку", "убратьадминку", "删除管理员", "admin-remover"], "{id}", GetString("CommandDescription.DeleteAdmin"), Command.UsageLevels.Host, Command.UsageTimes.Always, DeleteAdminCommand, true, false, [GetString("CommandArgs.DeleteAdmin.Id")]),
// Commands with action handled elsewhere
new(["shoot", "guess", "bet", "bt", "st", "угадать", "бт", "猜测", "赌", "adivinhar"], "{id} {role}", GetString("CommandDescription.Guess"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, (_, _, _) => { }, true, false, [GetString("CommandArgs.Guess.Id"), GetString("CommandArgs.Guess.Role")]),
@@ -221,12 +225,16 @@ internal static class ChatCommands
private static string[] ModsFileCache = [];
private static string[] VIPsFileCache = [];
private static string[] AdminsFileCache = [];
private static long LastModFileUpdate;
private static long LastVIPFileUpdate;
private static long LastAdminFileUpdate;
// Function to check if a Player is Moderator
public static bool IsPlayerModerator(string friendCode)
{
if (IsPlayerAdmin(friendCode)) return true;
friendCode = friendCode.Replace(':', '#');
if (friendCode == "" || friendCode == string.Empty || !Options.ApplyModeratorList.GetBool()) return false;
@@ -234,7 +242,8 @@ internal static class ChatCommands
long now = Utils.TimeStamp;
string[] friendCodes;
if (LastModFileUpdate + 5 > now) { friendCodes = ModsFileCache; }
if (LastModFileUpdate + 5 > now)
friendCodes = ModsFileCache;
else
{
var friendCodesFilePath = $"{Main.DataPath}/EHR_DATA/Moderators.txt";
@@ -262,7 +271,8 @@ internal static class ChatCommands
long now = Utils.TimeStamp;
string[] friendCodes;
if (LastVIPFileUpdate + 5 > now) { friendCodes = VIPsFileCache; }
if (LastVIPFileUpdate + 5 > now)
friendCodes = VIPsFileCache;
else
{
var friendCodesFilePath = $"{Main.DataPath}/EHR_DATA/VIPs.txt";
@@ -280,6 +290,35 @@ internal static class ChatCommands
return friendCodes.Any(code => code.Contains(friendCode, StringComparison.OrdinalIgnoreCase));
}
// Function to check if a player is an Admin
public static bool IsPlayerAdmin(string friendCode)
{
friendCode = friendCode.Replace(':', '#');
if (friendCode == "" || friendCode == string.Empty || !Options.ApplyAdminList.GetBool()) return false;
long now = Utils.TimeStamp;
string[] friendCodes;
if (LastAdminFileUpdate + 5 > now)
friendCodes = AdminsFileCache;
else
{
var friendCodesFilePath = $"{Main.DataPath}/EHR_DATA/Admins.txt";
if (!File.Exists(friendCodesFilePath))
{
File.WriteAllText(friendCodesFilePath, string.Empty);
return false;
}
friendCodes = AdminsFileCache = File.ReadAllLines(friendCodesFilePath);
LastAdminFileUpdate = now;
}
return friendCodes.Any(code => code.Contains(friendCode, StringComparison.OrdinalIgnoreCase));
}
public static bool Prefix(ChatController __instance)
{
if (__instance.quickChatField.visible) return true;
@@ -411,7 +450,7 @@ internal static class ChatCommands
}
}
private static void RequestCommandProcessingFromHost(string methodName, string text, bool modCommand = false)
private static void RequestCommandProcessingFromHost(string methodName, string text, bool modCommand = false, bool adminCommand = false)
{
PlayerControl pc = PlayerControl.LocalPlayer;
MessageWriter w = AmongUsClient.Instance.StartRpcImmediately(pc.NetId, (byte)CustomRPC.RequestCommandProcessing, SendOption.Reliable, AmongUsClient.Instance.HostId);
@@ -419,11 +458,57 @@ internal static class ChatCommands
w.Write(pc.PlayerId);
w.Write(text);
w.Write(modCommand);
w.Write(adminCommand);
AmongUsClient.Instance.FinishRpcImmediately(w);
}
// ---------------------------------------------------------------------------------------------------------------------------------------------
private static void DeleteAdminCommand(PlayerControl player, string text, string[] args)
{
if (!AmongUsClient.Instance.AmHost)
{
RequestCommandProcessingFromHost(nameof(DeleteAdminCommand), text);
return;
}
if (args.Length < 2 || !byte.TryParse(args[1], out byte remAdminId)) return;
PlayerControl remAdminPc = Utils.GetPlayerById(remAdminId);
if (remAdminPc == null) return;
string remFc = remAdminPc.FriendCode.Replace(':', '#');
if (!IsPlayerAdmin(remFc))
{
Utils.SendMessage(GetString("PlayerNotAdmin"), player.PlayerId);
return;
}
File.WriteAllLines($"{Main.DataPath}/EHR_DATA/Admins.txt", File.ReadAllLines($"{Main.DataPath}/EHR_DATA/Admins.txt").Where(x => !x.Contains(remFc)));
Utils.SendMessage(GetString("PlayerRemovedFromAdminList"), player.PlayerId);
}
private static void AddAdminCommand(PlayerControl player, string text, string[] args)
{
if (!AmongUsClient.Instance.AmHost)
{
RequestCommandProcessingFromHost(nameof(AddAdminCommand), text);
return;
}
if (args.Length < 2 || !byte.TryParse(args[1], out byte newAdminId)) return;
PlayerControl newAdminPc = Utils.GetPlayerById(newAdminId);
if (newAdminPc == null) return;
string fc = newAdminPc.FriendCode.Replace(':', '#');
if (IsPlayerModerator(fc)) Utils.SendMessage(GetString("PlayerAlreadyAdmin"), player.PlayerId);
File.AppendAllText($"{Main.DataPath}/EHR_DATA/Admins.txt", $"\n{fc}");
Utils.SendMessage(GetString("PlayerAddedToAdminList"), player.PlayerId);
}
private static void CopyPresetCommand(PlayerControl player, string text, string[] args)
{
if (args.Length < 3 || !int.TryParse(args[1], out int sourcePresetId) || sourcePresetId is < 1 or > 10 || (!int.TryParse(args[2], out int targetPreset) && targetPreset is < 1 or > 10)) return;
@@ -1582,10 +1667,12 @@ internal static class ChatCommands
{
if (!AmongUsClient.Instance.AmHost)
{
RequestCommandProcessingFromHost(nameof(EndCommand), text);
RequestCommandProcessingFromHost(nameof(EndCommand), text, adminCommand: true);
return;
}
if (!player.IsHost() && !IsPlayerAdmin(player.FriendCode)) return;
CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Draw);
GameManager.Instance.LogicFlow.CheckEndCriteria();
}
@@ -1704,10 +1791,12 @@ internal static class ChatCommands
{
if (!AmongUsClient.Instance.AmHost)
{
RequestCommandProcessingFromHost(nameof(ExeCommand), text);
RequestCommandProcessingFromHost(nameof(ExeCommand), text, adminCommand: true);
return;
}
if (!player.IsHost() && !IsPlayerAdmin(player.FriendCode)) return;
if (GameStates.IsLobby)
{
Utils.SendMessage(GetString("Message.CanNotUseInLobby"), player.PlayerId, sendOption: SendOption.None);
@@ -2303,7 +2392,12 @@ internal static class ChatCommands
if (remModPc == null) return;
string remFc = remModPc.FriendCode.Replace(':', '#');
if (!IsPlayerModerator(remFc)) Utils.SendMessage(GetString("PlayerNotMod"), player.PlayerId);
if (!IsPlayerModerator(remFc))
{
Utils.SendMessage(GetString("PlayerNotMod"), player.PlayerId);
return;
}
File.WriteAllLines($"{Main.DataPath}/EHR_DATA/Moderators.txt", File.ReadAllLines($"{Main.DataPath}/EHR_DATA/Moderators.txt").Where(x => !x.Contains(remFc)));
Utils.SendMessage(GetString("PlayerRemovedFromModList"), player.PlayerId);
@@ -2323,7 +2417,12 @@ internal static class ChatCommands
if (newModPc == null) return;
string fc = newModPc.FriendCode.Replace(':', '#');
if (IsPlayerModerator(fc)) Utils.SendMessage(GetString("PlayerAlreadyMod"), player.PlayerId);
if (IsPlayerModerator(fc))
{
Utils.SendMessage(GetString("PlayerAlreadyMod"), player.PlayerId);
return;
}
File.AppendAllText($"{Main.DataPath}/EHR_DATA/Moderators.txt", $"\n{fc}");
Utils.SendMessage(GetString("PlayerAddedToModList"), player.PlayerId);
+11
View File
@@ -33,6 +33,17 @@ public static class GameStartManagerPatch
private static TextMeshPro WarningText;
public static float Timer => Math.Max(0, 597f - (Utils.TimeStamp - TimerStartTS));
[HarmonyPatch(typeof(TimerTextTMP), nameof(TimerTextTMP.GetTextString))]
private static class TimerTextTMPGetTextStringPatch
{
public static bool Prefix(TimerTextTMP __instance, ref string __result)
{
int seconds = __instance.GetSecondsRemaining();
__result = string.Format(GetString("LobbyTimer"), seconds / 60, seconds % 60);
return false;
}
}
[HarmonyPatch(typeof(GameStartManager), nameof(GameStartManager.Start))]
public static class GameStartManagerStartPatch
{
+1 -1
View File
@@ -421,7 +421,7 @@ internal static class CheckForEndVotingPatch
case 2:
name = string.Format(GetString("PlayerIsRole"), coloredRealName, coloredRole);
if (Options.ShowTeamNextToRoleNameOnEject.GetBool())
if (Options.ShowTeamNextToRoleNameOnEject.GetBool() && !(crole.IsVanilla() || crole.ToString().EndsWith("EHR")))
{
name += " (";
CustomTeamManager.CustomTeam team = CustomTeamManager.GetCustomTeam(player.PlayerId);
+17 -15
View File
@@ -206,21 +206,23 @@ You can also report bugs and suggest features in the #bug-reports and #suggestio
:x: Can never use the command<br>
:question: Host setting determines<br>
| Feature | Regular Players | VIP | Moderator | Host |
|-----------|-----------------|--------------------|--------------------|--------------------|
| /color | :question: | :heavy_check_mark: | :question: | :heavy_check_mark: |
| /rename | :question: | :heavy_check_mark: | :question: | :heavy_check_mark: |
| /tpin | :question: | :heavy_check_mark: | :question: | :heavy_check_mark: |
| /tpout | :question: | :heavy_check_mark: | :question: | :heavy_check_mark: |
| /kick | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
| /ban | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
| /say | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
| /poll | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
| /mute | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
| /ds | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
| /gmpoll | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
| /fix | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
| Lobby tag | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
| Feature | Regular Players | VIP | Moderator | Admin | Host |
|-----------|-----------------|--------------------|--------------------|--------------------|--------------------|
| /color | :question: | :heavy_check_mark: | :question: | :question: | :heavy_check_mark: |
| /rename | :question: | :heavy_check_mark: | :question: | :question: | :heavy_check_mark: |
| /tpin | :question: | :heavy_check_mark: | :question: | :question: | :heavy_check_mark: |
| /tpout | :question: | :heavy_check_mark: | :question: | :question: | :heavy_check_mark: |
| /kick | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
| /ban | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
| /say | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
| /poll | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
| /mute | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
| /ds | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
| /gmpoll | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
| /fix | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
| /exe | :x: | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
| /end | :x: | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |
| Lobby tag | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
<br>
+13 -1
View File
@@ -1865,6 +1865,7 @@
"DisableCrackedGlass": "Disable Cracked Glass on Meeting Screen",
"ApplyModeratorList": "Apply Moderator List",
"ApplyVIPList": "Apply VIP List",
"ApplyAdminList": "Apply Admin List",
"KickCommandDisabled": "The kick command is currently disabled.",
"KickCommandNoAccess": "You do not have access to the kick command.",
"KickCommandInvalidID": "Invalid player ID specified.\\nPlease use '/kick [playerID]' to kick a player.",
@@ -1874,6 +1875,7 @@
"KickCommandKickedRole": "Their role was",
"ModeratorTag": "<#8000ff>Moderator</color>",
"VIPTag": "<#ffff00>VIP</color>",
"AdminTag": "<#ff0000>Admin</color>",
"EnableAFKDetector": "Enable AFK Detector (Also Used To Detect And Fix Black Screens)",
"AFKWarning": "<#ffff00><size=90%>Please move to avoid being marked as AFK</color> <#ffffff>({0})</size></color>",
"AFKSuffix": "<#ffa500>(AFK)</color>",
@@ -2364,7 +2366,8 @@
"EnabledGMWarning": "You have enabled Game Master. This will make you a ghost at the start of every game. Due to an unknown issue, games may end with the 'Everyone died' reason instantly, if this happens, please disable Game Master.",
"Commands.NoAccess.Level.Host": "<#ff5555>X <#bb0000>This command can only be used by <#ffffff>The Host",
"Commands.NoAccess.Level.Modded": "<#ff5555>X <#bb0000>This command can only be used by <#ffffff>Modded Clients",
"Commands.NoAccess.Level.HostOrModerator": "<#ff5555>X <#bb0000>This command can only be used by <#ffffff>The Host & Moderators",
"Commands.NoAccess.Level.HostOrModerator": "<#ff5555>X <#bb0000>This command can only be used by <#ffffff>The Host & Moderators & Admins",
"Commands.NoAccess.Level.HostOrAdmin": "<#ff5555>X <#bb0000>This command can only be used by <#ffffff>The Host & Admins",
"Commands.NoAccess.Time.InLobby": "<#ff5555>X</color> <#bb0000>This command can only be used <#ffffff>In Lobby",
"Commands.NoAccess.Time.InGame": "<#ff5555>X</color> <#bb0000>This command can only be used <#ffffff>In Game",
"Commands.NoAccess.Time.InMeeting": "<#ff5555>X</color> <#bb0000>This command can only be used <#ffffff>In Meetings",
@@ -2462,6 +2465,8 @@
"CommandDescription.Forge": "As the Forger, forge a fake role for a player.",
"CommandDescription.Choose": "Choose your role as the Pawn after completing all tasks.",
"CommandDescription.CopyPreset": "Copy all settings from a preset to another preset.",
"CommandDescription.AddAdmin": "Add a player to the list of admins",
"CommandDescription.DeleteAdmin": "Remove a player from the list of admins",
"CommandArgs.ChangeSetting.Name": "The setting's name to change (leave blank to view all settings)",
"CommandArgs.ChangeSetting.UnknownValue": "(leave blank to view what to put here)",
"CommandArgs.Rename.Name": "Your new name",
@@ -2548,6 +2553,8 @@
"CommandArgs.Choose.Role": "The role to choose",
"CommandArgs.CopyPreset.SourcePreset": "The preset to copy all settings from",
"CommandArgs.CopyPreset.TargetPreset": "The preset to paste all settings to",
"CommandArgs.AddAdmin.Id": "The player's ID to add to the list of admins",
"CommandArgs.DeleteAdmin.Id": "The player's ID to remove from the list of admins",
"Commands.ChangeSettingHelp": "<b><u>Arguments:</u></b><size=70%>\\n- map (theskeld/mirahq/polus/dlekseht/airship/thefungle/custom)\\n- impostors (number)\\n- players (number)\\n- recommended (on/off)\\n- confirmejects (on/off)\\n- emergencymeetings (number)\\n- anonymousvotes (on/off)\\n- emergencycooldown (number)\\n- discussiontime (number)\\n- votingtime (number)\\n- playerspeed (float)\\n- crewmatevision (float)\\n- impostorvision (float)\\n- killcooldown (float)\\n- killdistance (short/medium/long/custom)\\n- taskbarupdates (always/meetings/never)\\n- visualtasks (on/off)\\n- commontasks (number)\\n- longtasks (number)\\n- shorttasks (number)\\n- scientistcount (number)\\n- scientistchance (number)\\n- vitalsdisplaycooldown (float)\\n- batteryduration (float)\\n- engineercount (number)\\n- engineerchance (number)\\n- ventusecooldown (float)\\n- maxtimeinvents (float)\\n- guardianangelcount (number)\\n- guardianangelchance (number)\\n- protectcooldown (float)\\n- protectduration (float)\\n- protectvisibletoimpostors (on/off)\\n- shapeshiftercount (number)\\n- shapeshifterchance (number)\\n- shapeshiftduration (float)\\n- shapeshiftcooldown (float)\\n- leaveshapeshiftevidence (on/off)\\n- phantomcount (number)\\n- phantomchance (number)\\n- inviscooldown (float)\\n- invisduration (float)\\n- noisemakercount (number)\\n- noisemakerchance (number)\\n- noisemakerimpostoralert (on/off)\\n- noisemakeralertduration (number)\\n- trackercount (number)\\n- trackerchance (number)\\n- trackduration (float)\\n- trackcooldown (float)\\n- trackdelay (float)\\n- ghostdotasks (on/off)\\n\\n<u><b>Notes:</b></u>\\n1. Upper and lowercase matters\\n2. Where it says custom, you obviously put a number argument after it\\n3. A float is a single precision floating number, like 1.7\\n4. \"ghostdotasks\" causes issues if you set it\\n5. Example uses:\\n - \"/cs map polus\"\\n - \"/cs killdistance custom 4\"\\n - \"/cs trackdelay 1,7\"\\n - \"/cs confirmejects on\"",
"AddTagSuccess": "<#00ffa5>✓</color> Suceessfully created the tag {0} for {1}. If you want to change it, just use this command again and it will override the current tag. To delete it, simply type <#00a5ff>/deletetag {2}</color>!",
"DeleteTagSuccess": "<#00ffa5>✓</color> Successfully deleted {0}'s tag.",
@@ -8688,6 +8695,10 @@
"PlayerAddedToVIPList": "Player successfully added to the VIP list.",
"PlayerRemovedFromVIPList": "Player successfully removed from the VIP list.",
"PlayerNotVIP": "This player is not a VIP, nothing was changed.",
"PlayerNotAdmin": "This player is not an admin, nothing was changed.",
"PlayerRemovedFromAdminList": "Player successfully removed from the admin list.",
"PlayerAlreadyAdmin": "This player is already an admin, nothing was changed.",
"PlayerAddedToAdminList": "Player successfully added to the admin list.",
"Goose": "Goose",
"GooseInfo": "Honk at players to annoy them",
"GooseInfoLong": "(Crewmates):\\nAs the Goose, you can honk at players to annoy them. You can drag them around and make them unable to use their abilities while you're honking at them.",
@@ -9701,6 +9712,7 @@
"SubmergedRoomName.133": "Ballast",
"SubmergedRoomName.134": "Lower Central",
"SubmergedRoomName.135": "Lower Lobby",
"LobbyTimer": "Lobby closes in {0}m {1}s",
"ModLanguage": "Mod Language",
"UseGameLanguage": "Use Game Language",
"Hungarian": "Hungarian",
+1 -1
View File
@@ -120,7 +120,7 @@ public class Addict : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = VentCooldown.GetFloat();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnEnterVent(PlayerControl pc, Vent vent)
+1 -1
View File
@@ -134,7 +134,7 @@ internal class Adventurer : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnExitVent(PlayerControl pc, Vent vent)
+1 -1
View File
@@ -262,7 +262,7 @@ public class Alchemist : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = VentCooldown.GetFloat();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
bool OnCoEnterVent(PlayerPhysics instance, int ventId)
+1 -1
View File
@@ -57,7 +57,7 @@ public class Altruist : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public static bool OnAnyoneCheckReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target)
+1 -1
View File
@@ -50,7 +50,7 @@ public class Astral : RoleBase
if (Options.UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = AbilityCooldown.GetFloat();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
try { AURoleOptions.GuardianAngelCooldown = 900f; }
catch { }
+1 -1
View File
@@ -79,7 +79,7 @@ public class CameraMan : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = VentCooldown.GetFloat();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnEnterVent(PlayerControl pc, Vent vent)
+1 -1
View File
@@ -85,7 +85,7 @@ public class Catcher : RoleBase
if (Options.UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = AbilityCooldown.GetFloat();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
private void PlaceTrap(PlayerControl pc)
+1 -1
View File
@@ -41,7 +41,7 @@ public class Clairvoyant : RoleBase
if (Options.UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
private static void UseAbility(PlayerControl pc)
+1 -1
View File
@@ -47,7 +47,7 @@ internal class Convener : RoleBase
if (Options.UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = CD.GetFloat();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnPet(PlayerControl pc)
+1 -1
View File
@@ -183,7 +183,7 @@ public class Dad : RoleBase
}
AURoleOptions.EngineerCooldown = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnReportDeadBody()
+1 -1
View File
@@ -49,7 +49,7 @@ internal class DovesOfNeace : RoleBase
if (UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = DovesOfNeaceCooldown.GetFloat();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void SetButtonTexts(HudManager hud, byte id)
+1 -1
View File
@@ -60,7 +60,7 @@ public class Drainer : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte id)
{
AURoleOptions.EngineerCooldown = VentCD.GetFloat();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public static void OnAnyoneExitVent(PlayerControl pc)
+1 -1
View File
@@ -78,7 +78,7 @@ public class Druid : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = VentCooldown.GetInt();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public static void SendRPCAddTrigger(bool add, byte playerId, Vector2 position, string roomName = "")
+1 -1
View File
@@ -62,7 +62,7 @@ internal class Grenadier : RoleBase
if (UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = GrenadierSkillCooldown.GetFloat();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override string GetProgressText(byte playerId, bool comms)
+1 -1
View File
@@ -62,7 +62,7 @@ internal class Lighter : RoleBase
{
if (!UsePets.GetBool())
{
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
AURoleOptions.EngineerCooldown = LighterSkillCooldown.GetFloat();
}
+1 -1
View File
@@ -43,7 +43,7 @@ internal class Mayor : RoleBase
? opt.GetInt(Int32OptionNames.EmergencyCooldown)
: 300f;
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void SetButtonTexts(HudManager hud, byte id)
+1 -1
View File
@@ -35,7 +35,7 @@ internal class Mole : RoleBase
{
if (UsePets.GetBool()) return;
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
AURoleOptions.EngineerCooldown = CD.GetFloat();
}
+1 -1
View File
@@ -86,7 +86,7 @@ public class NiceHacker : RoleBase
if (UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = AbilityCD.GetFloat();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public static void SendRPC(byte playerId, float secondsLeft)
+1 -1
View File
@@ -71,7 +71,7 @@ public class Oxyman : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = 0f;
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnEnterVent(PlayerControl pc, Vent vent)
+1 -1
View File
@@ -49,7 +49,7 @@ internal class Paranoia : RoleBase
? ParanoiaVentCooldown.GetFloat()
: 300f;
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void SetButtonTexts(HudManager hud, byte id)
+1 -1
View File
@@ -55,7 +55,7 @@ internal class Perceiver : RoleBase
if (Options.UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = CD.GetFloat();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnPet(PlayerControl pc)
+1 -1
View File
@@ -80,7 +80,7 @@ public class Rhapsode : RoleBase
if (Options.UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = AbilityCooldown.GetInt();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnEnterVent(PlayerControl pc, Vent vent)
+1 -1
View File
@@ -51,7 +51,7 @@ internal class SecurityGuard : RoleBase
{
if (UsePets.GetBool()) return;
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
AURoleOptions.EngineerCooldown = SecurityGuardSkillCooldown.GetFloat();
}
+1 -1
View File
@@ -182,7 +182,7 @@ internal class Sentinel : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = PatrolCooldown.GetFloat();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnFixedUpdate(PlayerControl pc)
+1 -1
View File
@@ -64,7 +64,7 @@ public class Telekinetic : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = 0f;
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void OnFixedUpdate(PlayerControl pc)
+1 -1
View File
@@ -111,7 +111,7 @@ public class Tether : RoleBase
if (UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = VentCooldown.GetFloat();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override bool OnVote(PlayerControl pc, PlayerControl target)
+1 -1
View File
@@ -66,7 +66,7 @@ internal class TimeMaster : RoleBase
if (UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = TimeMasterSkillCooldown.GetFloat();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override void SetButtonTexts(HudManager hud, byte id)
+1 -1
View File
@@ -57,7 +57,7 @@ internal class Ventguard : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
AURoleOptions.EngineerCooldown = 15f;
}
+1 -1
View File
@@ -54,7 +54,7 @@ internal class Veteran : RoleBase
if (UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown = VeteranSkillCooldown.GetFloat();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override string GetProgressText(byte playerId, bool comms)
+1 -1
View File
@@ -45,7 +45,7 @@ public class Magistrate : RoleBase
{
if (AbilityTrigger != AbilityTriggers.Vent) return;
AURoleOptions.EngineerCooldown = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override bool CanUseImpostorVentButton(PlayerControl pc)
+1 -1
View File
@@ -49,7 +49,7 @@ internal class Mario : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = MarioVentCD.GetFloat();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
}
public override string GetProgressText(byte playerId, bool comms)
+1 -1
View File
@@ -47,7 +47,7 @@ public class Tank : RoleBase
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.EngineerCooldown = VentCooldown.GetFloat();
AURoleOptions.EngineerInVentMaxTime = 0.1f;
AURoleOptions.EngineerInVentMaxTime = 0.3f;
Main.AllPlayerSpeed[playerId] = Speed.GetFloat();
}