Compare commits

..
20 Commits
Author SHA1 Message Date
Crowdin Bot 81e2d4e2d5 chore: update translations for release 7.1.3 2026-01-15 11:04:31 +00:00
Gurge44 2c05cd6b99 changelog 2026-01-15 12:01:39 +01:00
Gurge44 c458d15c02 swap 2026-01-15 12:00:36 +01:00
Gurge44 4ba0049bf3 wait a bit just to make sure 2026-01-15 11:58:51 +01:00
Gurge44 a962374eeb ACTUALLY FIX KICKING OMG 2026-01-15 11:55:17 +01:00
Gurge44 7e7f30b75e fix gm list 2026-01-14 10:42:48 +01:00
Gurge44 15e073c932 Merge remote-tracking branch 'origin/main' 2026-01-14 10:09:35 +01:00
Gurge44 14229f6a53 7.1.2 2026-01-14 10:09:07 +01:00
Jamesssssssssssssss fdffd045db Build Steam ZIP using x86 BepInEx & Add automatic Discord #releases ping on release (#471)
* Update release.yml to build Steam ZIP correctly

Apparently steam uses x86 BepInEx, who knew

* Distinguish bepinex.zip file names

* Add #releases ping

* Better release secret name
2026-01-14 09:54:25 +01:00
Gurge44 6e25888b7f major fix in CustomRpcSender.cs 2026-01-14 09:19:44 +01:00
Gurge44 def0087782 Merge remote-tracking branch 'origin/main' 2026-01-14 08:22:27 +01:00
Gurge44 df18bb1064 fix 2026-01-14 08:22:12 +01:00
Crowdin Bot f4ba0eba1b chore: update translations for release 7.1.1 2026-01-13 18:47:45 +00:00
Gurge44 ff5b0f64f1 changelog 2026-01-13 19:43:12 +01:00
Gurge44 25c18c1194 patch dangerous au code 2026-01-13 19:40:55 +01:00
Gurge44 15a1c25264 fix string 2026-01-13 14:13:56 +01:00
Gurge44 6ee16dec9c CNOs are bye bye on vanilla regions 2026-01-13 13:58:57 +01:00
Gurge44 d13d523db1 Merge remote-tracking branch 'origin/main' 2026-01-13 13:49:59 +01:00
Gurge44 bf7efbce77 fix kicking? 2026-01-13 13:49:47 +01:00
Jamesssssssssssssss 721e9de8f4 Update release.yml (#470)
package steam properly
add changelog.md file instead of just writing the words :/
2026-01-13 10:25:53 +01:00
23 changed files with 257 additions and 180 deletions

No files matched your search

+36 -13
View File
@@ -113,35 +113,49 @@ jobs:
name: ehr
path: artifacts/ehr
- name: Prepare release folder
run: mkdir -p release
- name: Prepare release folders
run: |
mkdir -p epic
mkdir -p steam
- name: Download BepInEx 6 pre-release 735
run: |
curl -L https://builds.bepinex.dev/projects/bepinex_be/735/BepInEx-Unity.IL2CPP-win-x64-6.0.0-be.735%2B5fef357.zip -o bepinex.zip
unzip bepinex.zip -d release
chmod -R u+rwX,go+rX release
curl -L https://builds.bepinex.dev/projects/bepinex_be/735/BepInEx-Unity.IL2CPP-win-x64-6.0.0-be.735%2B5fef357.zip -o bepinex-x64.zip
unzip bepinex-x64.zip -d epic
chmod -R u+rwX,go+rX epic
curl -L https://builds.bepinex.dev/projects/bepinex_be/735/BepInEx-Unity.IL2CPP-win-x86-6.0.0-be.735%2B5fef357.zip -o bepinex-x86.zip
unzip bepinex-x86.zip -d steam
chmod -R u+rwX,go+rX steam
- name: Copy EHR dll to plugins
run: cp artifacts/ehr/EHR.dll release/BepInEx/plugins/
run: |
cp artifacts/ehr/EHR.dll epic/BepInEx/plugins/
cp artifacts/ehr/EHR.dll steam/BepInEx/plugins/
- name: Copy configs to BepInEx config
run: |
mkdir -p release/BepInEx/config/
cp packaging/* release/BepInEx/config/
mkdir -p epic/BepInEx/config/
mkdir -p steam/BepInEx/config/
cp packaging/* epic/BepInEx/config/
cp packaging/* steam/BepInEx/config/
- name: Download modded regions DLL to plugins
run: curl -L https://github.com/miniduikboot/Mini.RegionInstall/releases/download/v1.2.0/Mini.RegionInstall.dll -o release/BepInEx/plugins/Mini.RegionInstall.dll
run: |
curl -L https://github.com/miniduikboot/Mini.RegionInstall/releases/download/v1.2.0/Mini.RegionInstall.dll -o epic/BepInEx/plugins/Mini.RegionInstall.dll
cp epic/BepInEx/plugins/Mini.RegionInstall.dll steam/BepInEx/plugins/Mini.RegionInstall.dll
- name: Steam App ID
run : echo "945360" > steam_appid.txt
- name: Create Epic/MS Store ZIP
run: |
cd release
cd epic
zip -r "../EHR.v${{ github.event.inputs.version }}_Epic-Games_Microsoft-Store.zip" .
- name: Create Steam ZIP
run: |
echo "945360" > steam_appid.txt
zip -r "EHR.v${{ github.event.inputs.version }}_Steam.zip" .
cd steam
zip -r "../EHR.v${{ github.event.inputs.version }}_Steam.zip" .
- name: Upload release artifacts
uses: actions/upload-artifact@v4
@@ -189,7 +203,7 @@ jobs:
tag_name: "v${{ github.event.inputs.version }}"
name: "EHR v${{ github.event.inputs.version }}"
generate_release_notes: true
body: ${cat CHANGELOG.md}
body_path: CHANGELOG.md
files: |
release-artifacts/zips/*
release-artifacts/ehr/EHR.dll
@@ -212,3 +226,12 @@ jobs:
MODNEWS_API_URL: ${{ secrets.MODNEWS_API_URL }}
MODNEWS_API_TOKEN: ${{ secrets.MODNEWS_API_TOKEN }}
run: python release_to_modnews.py
# -----------------------------
# Ping Release Channel
# -----------------------------
- name: Notify Discord
run: |
curl -H "Content-Type: application/json" \
-X POST \
-d "{\"content\": \"<@&1170671991343288391>\nEHR v${{ github.event.inputs.version }}\nhttps://github.com/${{ github.repository }}/releases/tag/v${{ github.event.inputs.version }}\"}" \
${{ secrets.DISCORD_RELEASE_WEBHOOK_URL }}
+1 -36
View File
@@ -1,40 +1,5 @@
# Thank you so much for finding and using EHR!
## Bug Fixes
- **Fixed the host being kicked after a player joins the lobby**
- Fixed Quiz "Hallway" not counting players outside of all normal rooms,
- Fixed Snowdown kicking the host
- Fixed draft choices not always being random and not respecting min/max neutrals
- Fixed a reason for some players not getting a pet (the main reason is still innersloth's unstable code)
- Many other very small fixes and improvements
## Changes
- EAC list auto-updates after every game
- Completely rewrote the role selection logic
- Chameleon can now use pet to go invisible
- Optimized the code for some roles
- Admins can use `/xor` and `/combo` fully
- Overheat no longer freezes for cooling down
## Semi-Compatibility with LevelImpostor maps
- Fixed post-ejection tasks not executing after custom ejection screens
- Fixed Room Rush and Natural Disasters ending the game with `An error occured` on custom maps
## Additions
- New role: Empress (Coven Miscellaneous)
- New setting for (Custom) Hide And Seek, Mingle, Natural Disasters, Solo PVP: `Chat During Game`
- New global settings:
- - `Auto Execute /readycheck After Joining The Lobby`
- - - `Delay Before Auto Executing /readycheck (After Joining The Lobby)`
- New settings for Time Master:
- - `Can Revive`
- - `The killer of the revived player gets an alert about the revival`
- - `The killer also gets an arrow towards the revived player`
- New settings for Plaguebearer:
- - `Announce Transformation (from Plaguebearer to Pestilence)`
-
> [!WARNING]
> Pretty much everything in this release is experimental, I had no time to test anything, this is just an emergency release so you can continue playing!
- ACTUALLY FIXED THE HOST GETTING KICKED ON VANILLA SERVERS
---
+2 -2
View File
@@ -42,8 +42,8 @@ public class Main : BasePlugin
private const string DebugKeyHash = "c0fd562955ba56af3ae20d7ec9e64c664f0facecef4b3e366e109306adeae29d";
private const string DebugKeySalt = "59687b";
private const string PluginGuid = "com.gurge44.endlesshostroles";
public const string PluginVersion = "7.1.0";
public const string PluginDisplayVersion = "7.1.0";
public const string PluginVersion = "7.1.3";
public const string PluginDisplayVersion = "7.1.3";
public const bool TestBuild = false;
public const string NeutralColor = "#ffab1b";
+1 -1
View File
@@ -177,7 +177,7 @@ namespace EHR
protected void CreateNetObject(string sprite, Vector2 position)
{
if (GameStates.IsEnded || !AmongUsClient.Instance.AmHost) return;
if (GameStates.IsEnded || !AmongUsClient.Instance.AmHost || GameStates.CurrentServerType == GameStates.ServerType.Vanilla) return;
Logger.Info($" Create Custom Net Object {GetType().Name} (ID {MaxId + 1}) at {position} - Time since game start: {Utils.TimeStamp - IntroCutsceneDestroyPatch.IntroDestroyTS}s", "CNO.CreateNetObject");
+2 -1
View File
@@ -103,8 +103,9 @@ internal static class CustomRoleSelector
switch (role)
{
case CustomRoles.Ventriloquist when GameStates.CurrentServerType == GameStates.ServerType.Vanilla:
case CustomRoles.Weatherman when Main.LIMap || GameStates.CurrentServerType == GameStates.ServerType.Vanilla:
case CustomRoles.RoomRusher when Main.LIMap:
case CustomRoles.Weatherman when Main.LIMap:
case CustomRoles.Doctor when Options.EveryoneSeesDeathReasons.GetBool():
case CustomRoles.LovingCrewmate or CustomRoles.LovingImpostor when !loversData.Spawning:
case CustomRoles.Commander when optImpNum <= 1 && Commander.CannotSpawnAsSoloImp.GetBool():
+20 -2
View File
@@ -40,6 +40,7 @@ public class CustomRpcSender
private int currentRpcTarget;
private State currentState = State.BeforeInit;
private int messages;
public MessageWriter stream;
private CustomRpcSender() { }
@@ -54,6 +55,7 @@ public class CustomRpcSender
this.log = log;
currentRpcTarget = -2;
onSendDelegate = () => { };
messages = 0;
currentState = State.Ready;
if (log) Logger.Info($"\"{name}\" is ready", "CustomRpcSender");
@@ -112,6 +114,12 @@ public class CustomRpcSender
// StartMessage processing
if (currentState == State.InRootMessage)
EndMessage(startNew: true);
else if (messages > 0) // state is Ready
{
doneStreams.Add(stream);
stream = MessageWriter.Get(sendOption);
messages = 0;
}
StartMessage(targetClientId);
}
@@ -135,7 +143,7 @@ public class CustomRpcSender
throw new InvalidOperationException(errorMsg);
}
if (stream.Length >= 1500 && sendOption == SendOption.Reliable && !dispose) Logger.Warn($"Large reliable packet \"{name}\" is sending ({stream.Length} bytes)", "CustomRpcSender");
if (stream.Length >= 1400 && sendOption == SendOption.Reliable && !dispose) Logger.Warn($"Large reliable packet \"{name}\" is sending ({stream.Length} bytes)", "CustomRpcSender");
else if (log || stream.Length > 3) Logger.Info($"\"{name}\" is finished (Length: {stream.Length}, dispose: {dispose}, sendOption: {sendOption})", "CustomRpcSender");
if (!dispose)
@@ -146,7 +154,7 @@ public class CustomRpcSender
doneStreams.ForEach(x =>
{
if (x.Length >= 1500 && sendOption == SendOption.Reliable) Logger.Warn($"Large reliable packet \"{name}\" is sending ({x.Length} bytes)", "CustomRpcSender");
if (x.Length >= 1400 && sendOption == SendOption.Reliable) Logger.Warn($"Large reliable packet \"{name}\" is sending ({x.Length} bytes)", "CustomRpcSender");
else if (log || x.Length > 3) sb.Append($" | {x.Length}");
AmongUsClient.Instance.SendOrDisconnect(x);
@@ -203,6 +211,7 @@ public class CustomRpcSender
{
doneStreams.Add(stream);
stream = MessageWriter.Get(sendOption);
messages = 0;
}
if (targetClientId < 0)
@@ -242,6 +251,7 @@ public class CustomRpcSender
{
doneStreams.Add(stream);
stream = MessageWriter.Get(sendOption);
messages = 0;
}
currentRpcTarget = -2;
@@ -272,6 +282,14 @@ public class CustomRpcSender
throw new InvalidOperationException(errorMsg);
}
if (messages >= 10)
{
EndMessage(startNew: true);
StartMessage(currentRpcTarget);
}
messages++;
stream.StartMessage(2);
stream.WritePacked(targetNetId);
stream.Write(callId);
+3 -3
View File
@@ -1535,7 +1535,7 @@ internal static class ExtendedPlayerControl
if (pc.AmOwner || pc == player || (!phantom && pc.IsModdedClient()) || (phantom && pc.IsImpostor())) continue;
var sender = CustomRpcSender.Create("RpcMakeInvisible", SendOption.Reliable);
sender.StartMessage(pc.GetClientId());
sender.StartMessage(pc.OwnerId);
sender.StartRpc(player.NetTransform.NetId, RpcCalls.SnapTo)
.WriteVector2(new Vector2(50f, 50f))
.Write(player.NetTransform.lastSequenceId)
@@ -1584,7 +1584,7 @@ internal static class ExtendedPlayerControl
if (pc.AmOwner || pc == player || (!phantom && pc.IsModdedClient()) || (phantom && pc.IsImpostor())) continue;
var sender = CustomRpcSender.Create("RpcMakeVisible", SendOption.Reliable);
sender.StartMessage(pc.GetClientId());
sender.StartMessage(pc.OwnerId);
sender.StartRpc(player.NetTransform.NetId, RpcCalls.SnapTo)
.WriteVector2(new Vector2(50f, 50f))
.Write((ushort)(player.NetTransform.lastSequenceId + 32767))
@@ -1617,7 +1617,7 @@ internal static class ExtendedPlayerControl
if (pc.AmOwner || pc == player || (!phantom && pc.IsModdedClient()) || (phantom && pc.IsImpostor())) continue;
var sender = CustomRpcSender.Create("RpcResetInvisibility", SendOption.Reliable);
sender.StartMessage(pc.GetClientId());
sender.StartMessage(pc.OwnerId);
sender.StartRpc(player.NetId, RpcCalls.Exiled)
.EndRpc();
RoleTypes role = Utils.GetRoleMap(pc.PlayerId, player.PlayerId).RoleType;
+7 -1
View File
@@ -1360,6 +1360,9 @@ public static class GuessManager
StringBuilder sb = new();
int textIndex = 0;
int messages = 0;
int packingLimit = 10;
var skipped = false;
PlayerControl guesser = guesserId.GetPlayer();
MessageWriter writer = MessageWriter.Get(SendOption.Reliable);
@@ -1388,8 +1391,9 @@ public static class GuessManager
if (textIndex % 3 == 0) sb.AppendLine();
else sb.Append(' ');
if (writer.Length > 500)
if (writer.Length > 500 || messages + 2 > packingLimit)
{
messages = 0;
writer.EndMessage();
AmongUsClient.Instance.SendOrDisconnect(writer);
writer.Clear(SendOption.Reliable);
@@ -1412,6 +1416,8 @@ public static class GuessManager
writer.Write(namePlateId);
writer.Write(pc.GetNextRpcSequenceId(RpcCalls.SetNamePlateStr));
writer.EndMessage();
messages += 2;
}
writer.EndMessage();
+50 -8
View File
@@ -166,11 +166,11 @@ public static class Utils
switch (Vector2.Distance(pc.Pos(), location))
{
case < 0.3f:
{
if (log) Logger.Warn($"Target ({pc.GetNameWithRole().RemoveHtmlTags()}) is too close to the destination - Teleporting canceled", "TP");
return false;
}
// case < 0.3f:
// {
// if (log) Logger.Warn($"Target ({pc.GetNameWithRole().RemoveHtmlTags()}) is too close to the destination - Teleporting canceled", "TP");
// return false;
// }
case < 1.5f when !GameStates.IsLobby:
{
if (log) Logger.Msg($"Target ({pc.GetNameWithRole().RemoveHtmlTags()}) is too close to the destination - Changed to SendOption.None", "TP");
@@ -1796,6 +1796,9 @@ public static class Utils
catch (Exception e) { ThrowException(e); }
}
public static bool TempReviveHostRunning;
private static Stopwatch TempReviveHostStopwatch;
public static void SendMultipleMessages(this IEnumerable<Message> messages, SendOption sendOption = SendOption.Reliable)
{
var sender = CustomRpcSender.Create("Utils.SendMultipleMessages", sendOption);
@@ -1838,7 +1841,34 @@ public static class Utils
text = text.Replace("color=", string.Empty);
title = title.Replace("color=", string.Empty);
PlayerControl sender = !addtoHistory ? PlayerControl.LocalPlayer : Main.AllAlivePlayerControls.MinBy(x => x.PlayerId) ?? Main.AllPlayerControls.MinBy(x => x.PlayerId) ?? PlayerControl.LocalPlayer;
PlayerControl sender = !addtoHistory || GameStates.CurrentServerType == GameStates.ServerType.Vanilla ? PlayerControl.LocalPlayer : Main.AllAlivePlayerControls.MinBy(x => x.PlayerId) ?? Main.AllPlayerControls.MinBy(x => x.PlayerId) ?? PlayerControl.LocalPlayer;
if (sender.AmOwner && (!sender.IsAlive() || sender.Data.IsDead))
{
if (!TempReviveHostRunning)
Main.Instance.StartCoroutine(TempReviveHost());
else
TempReviveHostStopwatch?.Restart();
IEnumerator TempReviveHost()
{
TempReviveHostRunning = true;
TempReviveHostStopwatch = Stopwatch.StartNew();
sender.Data.IsDead = false;
sender.Data.SendGameData();
while (TempReviveHostStopwatch.ElapsedMilliseconds < 1000)
yield return null;
if (!AmongUsClient.Instance.AmHost || GameStates.IsEnded || GameStates.IsLobby) yield break;
sender.Data.IsDead = true;
sender.Data.SendGameData();
TempReviveHostRunning = false;
}
}
if (sendTo != byte.MaxValue && receiver.AmOwner)
{
@@ -3196,14 +3226,18 @@ public static class Utils
public static void SendGameData()
{
int messages = 0;
int packingLimit = 10;
MessageWriter writer = MessageWriter.Get(SendOption.Reliable);
writer.StartMessage(5);
writer.Write(AmongUsClient.Instance.GameId);
foreach (NetworkedPlayerInfo playerinfo in GameData.Instance.AllPlayers)
{
if (writer.Length > 500)
if (writer.Length > 500 || messages >= packingLimit)
{
messages = 0;
writer.EndMessage();
AmongUsClient.Instance.SendOrDisconnect(writer);
writer.Clear(SendOption.Reliable);
@@ -3215,6 +3249,8 @@ public static class Utils
writer.WritePacked(playerinfo.NetId);
playerinfo.Serialize(writer, false);
writer.EndMessage();
messages++;
}
writer.EndMessage();
@@ -3224,6 +3260,9 @@ public static class Utils
public static void SendGameDataTo(int targetClientId)
{
int messages = 0;
int packingLimit = 10;
MessageWriter writer = MessageWriter.Get(SendOption.Reliable);
writer.StartMessage(6);
writer.Write(AmongUsClient.Instance.GameId);
@@ -3231,8 +3270,9 @@ public static class Utils
foreach (NetworkedPlayerInfo playerinfo in GameData.Instance.AllPlayers)
{
if (writer.Length > 500)
if (writer.Length > 500 || messages >= packingLimit)
{
messages = 0;
writer.EndMessage();
AmongUsClient.Instance.SendOrDisconnect(writer);
writer.Clear(SendOption.Reliable);
@@ -3245,6 +3285,8 @@ public static class Utils
writer.WritePacked(playerinfo.NetId);
playerinfo.Serialize(writer, false);
writer.EndMessage();
messages++;
}
writer.EndMessage();
+18
View File
@@ -125,6 +125,8 @@ internal static class ChatCommands
public static bool HasMessageDuringEjectionScreen;
private static bool WaitingToSend;
public static void LoadCommands()
{
Command.AllCommands = new Dictionary<string, Command>
@@ -466,6 +468,22 @@ internal static class ChatCommands
if (text.Contains("666") && PlayerControl.LocalPlayer.Is(CustomRoles.Demon))
Achievements.Type.WhatTheHell.Complete();
if (!canceled && AmongUsClient.Instance.AmHost && Utils.TempReviveHostRunning)
{
if (!WaitingToSend) Main.Instance.StartCoroutine(Wait());
return false;
IEnumerator Wait()
{
WaitingToSend = true;
while (Utils.TempReviveHostRunning && AmongUsClient.Instance.AmHost) yield return null;
yield return new WaitForSeconds(0.5f);
if (GameStates.IsEnded || GameStates.IsLobby) yield break;
WaitingToSend = false;
if (HudManager.InstanceExists) HudManager.Instance.Chat.SendChat();
}
}
return !canceled;
}
+5 -11
View File
@@ -359,13 +359,6 @@ internal static class GameEndChecker
try { LobbySharingAPI.NotifyLobbyStatusChanged(LobbyStatus.Ended); }
catch (Exception e) { ThrowException(e); }
string msg = GetString("NotifyGameEnding");
Main.AllPlayerControls
.Where(x => x.GetClient() != null && !x.Data.Disconnected)
.Select(x => new Message("\n", x.PlayerId, msg))
.SendMultipleMessages();
SetEverythingUpPatch.LastWinsReason = WinnerTeam is CustomWinner.Crewmate or CustomWinner.Impostor ? GetString($"GameOverReason.{reason}") : string.Empty;
var self = AmongUsClient.Instance;
self.StartCoroutine(CoEndGame(self, reason).WrapToIl2Cpp());
@@ -623,7 +616,7 @@ internal static class GameEndChecker
foreach (PlayerState playerState in statesCoutingAsCrew)
{
if (playerState.IsDead || !Options.CrewAdvancedGameEndCheckingSettings.TryGetValue(playerState.MainRole, out var option) || !option.GetBool()) continue;
if (!Options.CrewAdvancedGameEndCheckingSettings.TryGetValue(playerState.MainRole, out var option) || !option.GetBool() || playerState.SubRoles.Exists(x => x == CustomRoles.Madmate || x.IsConverted())) continue;
playerState.Role.ManipulateGameEndCheckCrew(playerState, out bool keepGameGoing, out int countsAs);
crewKeepsGameGoing |= keepGameGoing;
crew += countsAs - 1;
@@ -749,11 +742,12 @@ internal static class GameEndChecker
return true;
}
if (winner != null) ResetAndSetWinner((CustomWinner)winner);
if (winner.HasValue)
ResetAndSetWinner(winner.Value);
if (rl != null)
if (rl.HasValue)
{
WinnerRoles.Add((CustomRoles)rl);
WinnerRoles.Add(rl.Value);
WinnerIds.UnionWith(Main.AllPlayerControls.Where(x => x.GetCustomRole() == rl).Select(x => x.PlayerId));
}
+10
View File
@@ -28,6 +28,16 @@ internal static class MakePublicPatch
}
}*/
[HarmonyPatch(typeof(InnerNetClient), nameof(InnerNetClient.GetMaxMessagePackingLimit))]
static class GetMaxMessagePackingLimitPatch
{
public static bool Prefix(ref int __result)
{
__result = 10;
return false;
}
}
[HarmonyPatch(typeof(MMOnlineManager), nameof(MMOnlineManager.Start))]
// ReSharper disable once InconsistentNaming
internal static class MMOnlineManagerStartPatch
+24 -5
View File
@@ -1170,14 +1170,33 @@ public static class GameSettingMenuPatch
Vector3 gameSettingsLabelPos = gameSettingsLabel.transform.localPosition;
CustomGameMode[] gms = Enum.GetValues<CustomGameMode>()[..^1];
gms = gms.Without(CustomGameMode.TheMindGame).ToArray();
if (SubmergedCompatibility.Loaded && Main.NormalOptions.MapId == 6) gms = gms.Where(SubmergedCompatibility.IsSupported).ToArray();
int totalCols = Mathf.Max(1, Mathf.CeilToInt(gms.Length / 7f));
var gms = Enum.GetValues<CustomGameMode>()[..^1].ToList();
gms.Remove(CustomGameMode.TheMindGame);
if (GameStates.CurrentServerType == GameStates.ServerType.Vanilla)
{
gms.Remove(CustomGameMode.CaptureTheFlag);
gms.Remove(CustomGameMode.NaturalDisasters);
gms.Remove(CustomGameMode.BedWars);
}
if (SubmergedCompatibility.Loaded && Main.NormalOptions.MapId == 6)
gms.RemoveAll(SubmergedCompatibility.IsNotSupported);
if (Main.LIMap)
{
gms.Remove(CustomGameMode.CaptureTheFlag);
gms.Remove(CustomGameMode.Quiz);
gms.Remove(CustomGameMode.TheMindGame);
gms.Remove(CustomGameMode.BedWars);
gms.Remove(CustomGameMode.Deathrace);
}
int totalCols = 2;
GMButtons = [];
for (var index = 0; index < gms.Length; index++)
for (var index = 0; index < gms.Count; index++)
{
CustomGameMode gm = gms[index];
-2
View File
@@ -232,8 +232,6 @@ public static class GameStartManagerPatch
OptionItem.SyncAllOptions();
}
RPC.RpcVersionCheck();
GameStartManager.Instance.startState = GameStartManager.StartingStates.Countdown;
GameStartManager.Instance.countDownTimer = Options.AutoStartTimer.GetInt();
__instance?.StartButton.gameObject.SetActive(false);
+1
View File
@@ -31,6 +31,7 @@ internal static class HudManagerPatch
public static void ClearLowerInfoText()
{
if (LowerInfoText == null) return;
LowerInfoText.text = string.Empty;
}
+2 -1
View File
@@ -77,7 +77,6 @@ static class CoShowIntroPatch
{
while (!ShipStatus.Instance || !HudManager.InstanceExists) yield return null;
RPC.RpcVersionCheck();
GameStates.InGame = true;
__instance.IsIntroDisplayed = true;
@@ -103,6 +102,8 @@ static class CoShowIntroPatch
__instance.SetHudActive(true);
__instance.CrewmatesKilled.gameObject.SetActive(GameManager.Instance.ShowCrewmatesKilled());
GameManager.Instance.StartGame();
RPC.RpcVersionCheck();
}
IEnumerator CoBegin(IntroCutscene introCutscene)
+10 -1
View File
@@ -181,7 +181,16 @@ public static class MainMenuManagerPatch
buttonText.text = Translator.GetString($"MainMenu.{buttonName.Replace(" ", "")}");
}
__instance.PlayOnlineButton.OnClick.AddListener((UnityAction)(() => GameOptionsManager.Instance.Initialize()));
__instance.PlayOnlineButton.OnClick.AddListener((UnityAction)(() =>
{
GameOptionsManager.Instance.Initialize();
if (GameOptionsManager.Instance.normalGameHostOptions.MapId is 3 or > 5)
{
GameOptionsManager.Instance.normalGameHostOptions.MapId = 0;
GameOptionsManager.Instance.SaveNormalHostOptions();
}
}));
}
private static PassiveButton CreateButton(string name, Vector3 localPosition, Color32 normalColor, Color32 hoverColor, Action action, string label, Vector2? scale = null)
+2 -1
View File
@@ -22,7 +22,8 @@ internal static class CreateOptionsPickerPatch
[HarmonyPrefix]
public static void Prefix_SelectMap([HarmonyArgument(0)] ref int mapId)
{
if (mapId is > 5 or 3) mapId = 0;
if (mapId == 3)
mapId = 0;
}
[HarmonyPatch(typeof(GameOptionsMapPicker), nameof(GameOptionsMapPicker.SetupMapButtons))]
+2 -2
View File
@@ -809,8 +809,8 @@ internal static class MeetingHudStartPatch
}
if (Mortician.MsgToSend.TryGetValue(pc.PlayerId, out string value2)) AddMsg(value2, pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Mortician), GetString("MorticianCheckTitle")));
if (Medium.ContactPlayer.ContainsValue(pc.PlayerId)) AddMsg(string.Format(GetString("MediumshipNotifySelf"), Main.AllPlayerNames[Medium.ContactPlayer.FirstOrDefault(x => x.Value == pc.PlayerId).Key], pc.GetAbilityUseLimit()), pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medium), GetString("MediumshipTitle")));
if (Medium.ContactPlayer.ContainsKey(pc.PlayerId) && (!Medium.OnlyReceiveMsgFromCrew.GetBool() || pc.IsCrewmate())) AddMsg(string.Format(GetString("MediumshipNotifyTarget"), Main.AllPlayerNames[Medium.ContactPlayer[pc.PlayerId]]), pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medium), GetString("MediumshipTitle")));
if (Medium.ContactPlayer.ContainsValue(pc.PlayerId)) AddMsg(string.Format(GetString("MediumNotifySelf"), Main.AllPlayerNames[Medium.ContactPlayer.FirstOrDefault(x => x.Value == pc.PlayerId).Key], pc.GetAbilityUseLimit()), pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medium), GetString("MediumTitle")));
if (Medium.ContactPlayer.ContainsKey(pc.PlayerId) && (!Medium.OnlyReceiveMsgFromCrew.GetBool() || pc.IsCrewmate())) AddMsg(string.Format(GetString("MediumNotifyTarget"), Main.AllPlayerNames[Medium.ContactPlayer[pc.PlayerId]]), pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medium), GetString("MediumTitle")));
if (Virus.VirusNotify.TryGetValue(pc.PlayerId, out string value3)) AddMsg(value3, pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Virus), GetString("VirusNoticeTitle")));
if (Enigma.MsgToSend.TryGetValue(pc.PlayerId, out string value4)) AddMsg(value4, pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Enigma), Enigma.MsgToSendTitle[pc.PlayerId]));
+44 -49
View File
@@ -1413,52 +1413,56 @@ internal static class FixedUpdatePatch
public static void Postfix(PlayerControl __instance, bool lowLoad)
{
if (__instance == null || __instance.PlayerId >= 254) return;
CheckMurderPatch.Update(__instance.PlayerId);
if (AmongUsClient.Instance.AmHost && __instance.AmOwner)
CustomNetObject.FixedUpdate();
byte id = __instance.PlayerId;
if (AmongUsClient.Instance.AmHost && GameStates.IsInTask && ReportDeadBodyPatch.CanReport[id] && !id.IsPlayerRoleBlocked() && ReportDeadBodyPatch.WaitReport[id].Count > 0)
try
{
NetworkedPlayerInfo info = ReportDeadBodyPatch.WaitReport[id][0];
ReportDeadBodyPatch.WaitReport[id].Clear();
Logger.Info($"{__instance.GetNameWithRole().RemoveHtmlTags()}: Now that it is possible to report, we will process the report.", "ReportDeadBody");
__instance.ReportDeadBody(info);
}
if (__instance == null || __instance.PlayerId >= 254) return;
if (AmongUsClient.Instance.AmHost)
{
if (GhostRolesManager.AssignedGhostRoles.TryGetValue(id, out (CustomRoles Role, IGhostRole Instance) ghostRole))
CheckMurderPatch.Update(__instance.PlayerId);
if (AmongUsClient.Instance.AmHost && __instance.AmOwner)
CustomNetObject.FixedUpdate();
byte id = __instance.PlayerId;
if (AmongUsClient.Instance.AmHost && GameStates.IsInTask && ReportDeadBodyPatch.CanReport[id] && !id.IsPlayerRoleBlocked() && ReportDeadBodyPatch.WaitReport[id].Count > 0)
{
switch (ghostRole.Instance)
{
case Warden warden:
warden.Update(__instance);
break;
case Haunter haunter:
haunter.Update(__instance);
break;
case Bloodmoon bloodmoon:
Bloodmoon.Update(__instance, bloodmoon);
break;
}
NetworkedPlayerInfo info = ReportDeadBodyPatch.WaitReport[id][0];
ReportDeadBodyPatch.WaitReport[id].Clear();
Logger.Info($"{__instance.GetNameWithRole().RemoveHtmlTags()}: Now that it is possible to report, we will process the report.", "ReportDeadBody");
__instance.ReportDeadBody(info);
}
else if (!Main.HasJustStarted && GameStates.IsInTask && !ExileController.Instance && GhostRolesManager.ShouldHaveGhostRole(__instance))
GhostRolesManager.AssignGhostRole(__instance);
}
if (GameStates.InGame && Options.DontUpdateDeadPlayers.GetBool() && !(__instance.IsHost() && __instance.AmOwner) && !__instance.IsAlive() && !__instance.GetCustomRole().NeedsUpdateAfterDeath() && Options.CurrentGameMode is not CustomGameMode.RoomRush and not CustomGameMode.Quiz)
{
int buffer = Options.DeepLowLoad.GetBool() ? 150 : 60;
DeadBufferTime.TryAdd(id, buffer);
DeadBufferTime[id]--;
if (DeadBufferTime[id] > 0) return;
DeadBufferTime[id] = buffer;
if (AmongUsClient.Instance.AmHost)
{
if (GhostRolesManager.AssignedGhostRoles.TryGetValue(id, out (CustomRoles Role, IGhostRole Instance) ghostRole))
{
switch (ghostRole.Instance)
{
case Warden warden:
warden.Update(__instance);
break;
case Haunter haunter:
haunter.Update(__instance);
break;
case Bloodmoon bloodmoon:
Bloodmoon.Update(__instance, bloodmoon);
break;
}
}
else if (!Main.HasJustStarted && GameStates.IsInTask && !ExileController.Instance && GhostRolesManager.ShouldHaveGhostRole(__instance))
GhostRolesManager.AssignGhostRole(__instance);
}
if (GameStates.InGame && Options.DontUpdateDeadPlayers.GetBool() && !(__instance.IsHost() && __instance.AmOwner) && !__instance.IsAlive() && !__instance.GetCustomRole().NeedsUpdateAfterDeath() && Options.CurrentGameMode is not CustomGameMode.RoomRush and not CustomGameMode.Quiz)
{
int buffer = Options.DeepLowLoad.GetBool() ? 150 : 60;
DeadBufferTime.TryAdd(id, buffer);
DeadBufferTime[id]--;
if (DeadBufferTime[id] > 0) return;
DeadBufferTime[id] = buffer;
}
}
catch (Exception e) { ThrowException(e); }
try { DoPostfix(__instance, lowLoad); }
catch (Exception ex)
@@ -2422,15 +2426,6 @@ internal static class AssertWithTimeoutPatch
}
}
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.CmdCheckName))]
internal static class CmdCheckNameVersionCheckPatch
{
public static void Postfix()
{
RPC.RpcVersionCheck();
}
}
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.MixUpOutfit))]
public static class PlayerControlMixupOutfitPatch
{
+2 -26
View File
@@ -494,12 +494,6 @@ internal static class OnPlayerJoinedPatch
return;
}
if (!Main.PlayerVersion.ContainsKey(client.Character.PlayerId))
{
MessageWriter retry = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.RequestRetryVersionCheck, SendOption.None, client.Id);
AmongUsClient.Instance.FinishRpcImmediately(retry);
}
if (client.Character != null && client.Character.Data != null && (client.Character.Data.DefaultOutfit.ColorId < 0 || Palette.PlayerColors.Length <= client.Character.Data.DefaultOutfit.ColorId) && Main.AllPlayerControls.Length >= 17)
Disco.ChangeColor(client.Character);
}
@@ -530,7 +524,6 @@ internal static class OnPlayerJoinedPatch
}
BanManager.CheckBanPlayer(client);
RPC.RpcVersionCheck();
if (AmongUsClient.Instance.AmHost)
{
@@ -692,17 +685,9 @@ internal static class InnerNetClientSpawnPatch
if (Main.OverrideWelcomeMsg != "")
Utils.SendMessage(Main.OverrideWelcomeMsg, client.Character.PlayerId, sendOption: SendOption.None);
else
TemplateManager.SendTemplate("welcome", client.Character.PlayerId, true);
TemplateManager.SendTemplate("welcome", client.Character.PlayerId, true, sendOption: SendOption.None);
}, GameStates.CurrentServerType == GameStates.ServerType.Niko ? 7f : 3f, "Welcome Message");
LateTask.New(() =>
{
if (client.Character == null) return;
MessageWriter sender = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.RequestRetryVersionCheck, SendOption.Reliable, client.Character.OwnerId);
AmongUsClient.Instance.FinishRpcImmediately(sender);
}, 3f, "RPC Request Retry Version Check");
if (GameStates.IsOnlineGame && !client.Character.IsHost())
{
LateTask.New(() =>
@@ -713,7 +698,7 @@ internal static class InnerNetClientSpawnPatch
if (!client.Character.IsModdedClient())
{
// This kicks the host now on vanilla regions
// MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(LobbyBehaviour.Instance.NetId, (byte)RpcCalls.LobbyTimeExpiring, SendOption.None, client.Id);
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(LobbyBehaviour.Instance.NetId, (byte)RpcCalls.LobbyTimeExpiring, SendOption.None, client.Id);
// writer.WritePacked((int)GameStartManagerPatch.Timer);
// writer.Write(false);
// AmongUsClient.Instance.FinishRpcImmediately(writer);
@@ -831,15 +816,6 @@ internal static class PlayerControlCheckNamePatch
Logger.Warn($"Standard nickname: {playerName} => {name}", "Name Format");
playerName = name;
}
LateTask.New(() =>
{
if (__instance != null && !__instance.Data.Disconnected && !__instance.IsModdedClient())
{
MessageWriter sender = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.RequestRetryVersionCheck, SendOption.Reliable, __instance.OwnerId);
AmongUsClient.Instance.FinishRpcImmediately(sender);
}
}, 0.6f, "Retry Version Check", false);
}
}
+13 -13
View File
@@ -2,7 +2,7 @@
"LanguageID": "0",
"TextBelowVersionText": "",
"HostText": "مضيف - EHR",
"IconColor": "",
"IconColor": "00a5ff",
"HostColor": "#00ffa5",
"Icon": " | ",
"NameColor": "#00ffff",
@@ -58,20 +58,20 @@
"AddonSettingsNeut": "إعدادات <color=#ffab1b>المحايد</color>",
"ROT.Impostor_Killing": "★ الأدوار القاتلة",
"ROT.Impostor_Support": "★ الأدوار الداعمة",
"ROT.Impostor_Concealing": "★ Concealing Roles",
"ROT.Impostor_Miscellaneous": "★ Miscellaneous Roles",
"ROT.Impostor_Madmate": "★ Madmate Roles",
"ROT.Impostor_Concealing": "أدوار الإخفاء",
"ROT.Impostor_Miscellaneous": "أدوار متنوعة",
"ROT.Impostor_Madmate": "ادوار الطاقم الغاضب",
"ROT.Crewmate_Investigate": "★ أدوار التحقق",
"ROT.Crewmate_Support": "★ أدوار الدعم",
"ROT.Crewmate_Power": "★ أدوار القوة",
"ROT.Crewmate_Killing": "★ الأدوار القاتلة",
"ROT.Crewmate_Chaos": "★ أدوار الفوضى",
"ROT.Crewmate_Miscellaneous": "★ Miscellaneous Roles",
"ROT.Crewmate_Miscellaneous": "أدوار متنوعة",
"ROT.Neutral_Evil": "★ الأدوار الشريرة",
"ROT.Neutral_Pariah": "★ Pariah Roles",
"ROT.Neutral_Benign": "★ Benign Roles",
"ROT.Neutral_Killing": "★ الأدوار القاتلة",
"ROT.Coven_Miscellaneous": "★ Miscellaneous Roles",
"ROT.Coven_Miscellaneous": "أدوار متنوعة",
"ROT.Vanilla": "★ Vanilla Roles",
"ROT.Basic": "★ الأدوار العادية",
"ROT.AddonType.ImpOnly": "★ زوائد المحتال-فقط",
@@ -94,12 +94,12 @@
"RoleSubCategoryLimitOptions.Neutral_Benign.EnableLimit": "<#ffffff>Alter the number of</color> Neutral Benign <#ffffff>roles in the game</color>",
"RoleSubCategoryLimitOptions.Neutral_Killing.EnableLimit": "<#ffffff>Alter the number of</color> Neutral Killing <#ffffff>roles in the game</color>",
"RoleSubCategoryLimitOptions.Impostor_Killing.Min": "أصغر عدد أدوار المحتالين القاتلين",
"RoleSubCategoryLimitOptions.Impostor_Killing.Max": "Maximum Impostor Killing Roles",
"RoleSubCategoryLimitOptions.Impostor_Killing.Max": "أكبر عدد أدوار المحتالين القاتلين",
"RoleSubCategoryLimitOptions.Impostor_Support.Min": "Minimum Impostor Support Roles",
"RoleSubCategoryLimitOptions.Impostor_Support.Max": "Maximum Impostor Support Roles",
"RoleSubCategoryLimitOptions.Impostor_Concealing.Min": "Minimum Impostor Concealing Roles",
"RoleSubCategoryLimitOptions.Impostor_Concealing.Max": "Maximum Impostor Concealing Roles",
"RoleSubCategoryLimitOptions.Impostor_Miscellaneous.Min": "Minimum Impostor Miscellaneous Roles",
"RoleSubCategoryLimitOptions.Impostor_Concealing.Max": "الحد الأقصى لأدوار المحتالين الخفية",
"RoleSubCategoryLimitOptions.Impostor_Miscellaneous.Min": "الحد الأقصى لأدوار المحتالين المتنوعة",
"RoleSubCategoryLimitOptions.Impostor_Miscellaneous.Max": "Maximum Impostor Miscellaneous Roles",
"RoleSubCategoryLimitOptions.MadMates.Min": "Minimum Madmate Roles",
"RoleSubCategoryLimitOptions.MadMates.Max": "Maximum Madmate Roles",
@@ -121,8 +121,8 @@
"RoleSubCategoryLimitOptions.Neutral_Pariah.Max": "Maximum Neutral Pariah Roles",
"RoleSubCategoryLimitOptions.Neutral_Benign.Min": "Minimum Neutral Benign Roles",
"RoleSubCategoryLimitOptions.Neutral_Benign.Max": "Maximum Neutral Benign Roles",
"RoleSubCategoryLimitOptions.Neutral_Killing.Min": "Minimum Neutral Killing Roles",
"RoleSubCategoryLimitOptions.Neutral_Killing.Max": "Maximum Neutral Killing Roles",
"RoleSubCategoryLimitOptions.Neutral_Killing.Min": "أدنى حد للأدوار القاتلين المحايدين",
"RoleSubCategoryLimitOptions.Neutral_Killing.Max": "أقصى حد للأدوار القاتلين المحايدين",
"FactionLimits.Impostor.Min": "<#00ffa5>Minimum</color> <#ffffff>amount of</color> Impostor Roles",
"FactionLimits.Impostor.Max": "<#00a5ff>Maximum</color> <#ffffff>amount of</color> Impostor Roles",
"FactionLimits.Neutral.Min": "<#00ffa5>Minimum</color> <#ffffff>amount of</color> Neutral Roles",
@@ -10232,7 +10232,7 @@
"EnableAutoFactionMinMaxSettings": "Enable Automatic Team Size Adjustment Based on Player Count",
"AutoFactionMinMaxSettings.PlayerCap": "Minimum Player Threshold for These Settings to Apply (0 = unused)",
"AutoFactionMinMaxSettings.Applied": "[Auto Team Sizes] {0} players (>={1}) = {2} (<#ffff00>NNK</color>: <#ffffff>{3}-{4}</color>)",
"GMPoll.Allow": "Show {gm} in /gmpoll choices",
"GMPoll.Allow": "عرض {gm} في خيارات /gmpoll",
"MPoll.Allow": "Show {m} in /mpoll choices",
"MenuTitle.GMPoll": "Game Mode Poll",
"MenuTitle.MPoll": "Map Poll",
@@ -10268,6 +10268,6 @@
"Hungarian": "Hungarian",
"Polish": "Polish",
"Indonesian": "Indonesian",
"Persian": "Persian",
"Persian": "الفارسية",
"NotAssigned": "-"
}
+2 -2
View File
@@ -259,9 +259,9 @@ public static class SubmergedCompatibility
return (IList)Activator.CreateInstance(genericListType);
}
public static bool IsSupported(CustomGameMode mode)
public static bool IsNotSupported(CustomGameMode mode)
{
return mode is CustomGameMode.Standard or CustomGameMode.SoloPVP or CustomGameMode.FFA or CustomGameMode.StopAndGo or CustomGameMode.HotPotato or CustomGameMode.HideAndSeek or CustomGameMode.Speedrun or CustomGameMode.CaptureTheFlag or CustomGameMode.RoomRush or CustomGameMode.KingOfTheZones or CustomGameMode.Quiz or CustomGameMode.TheMindGame or CustomGameMode.BedWars;
return mode is CustomGameMode.NaturalDisasters;
}
public enum SubmergedSystemTypes : byte