Giter Site home page Giter Site logo

0xdrmoe / townofhost-enhanced Goto Github PK

View Code? Open in Web Editor NEW
61.0 9.0 68.0 43.24 MB

TOHE is the best Host-Only mod for anyone who wants to change their Among Us Experience!

Home Page: https://tohre.dev

License: GNU General Public License v3.0

C# 100.00%
among-us amongus enhanced host of tohe town townofhost csharp host-only mod modded modding

townofhost-enhanced's Introduction

Town of Host: Enhanced (TOHE)


Cover

Regarding this mod

This mod is not affiliated with Among Us or Innersloth LLC, and the content contained therein is not endorsed or otherwise sponsored by Innersloth LLC. Portions of the materials contained herein are the property of Innersloth LLC.




Credit to these mods and their developers for the code and help:

TOHRE

  • Town of Host: Enhanced was forked from Town of Host: Re-Edited.

TOHE :

  • Town of Host: Re-Edited was forked from Town of Host: Edited. (TONX)

TOH :

  • Our repo is based initially on Town of Host.

TOHY :

  • Many role ideas
  • Provided roles: AntiAdminer, CursedWolf, Workaholic, Greedier (Greedy), DarkHide (Stalker)
  • Reference: Modify game announcement

TOH:TOR :

  • Many role ideas
  • Reference: Exile Confirm
  • Reference: Split RPC Pack

SNR :

  • Reference: Credentials menu
  • Reference: Switch Horse Mode
  • Reference: Search Mod Game
  • Reference: Custom Button

TOP :

  • Reference: Zoom

RHR :

  • Reference: Modify settings menu

TOH+

  • Provided roles: Shapeshifter, Engineer, Scientist, Marshall, Poisoner, Necroview, Sidekick
  • Bait and Beartrap as add-ons
  • Ideas for some roles (such as Crusader)
  • Provided roles: Pyromaniac, Necromancer, Head Hunter (Huntsman), Alchemist, and others
  • Game Mode: FFA
  • Improved Role Summary
  • Dark Theme
  • Improved Role Spawns
  • Some ideas to improve performance
  • Provided roles: Swapper, Berserker, Randomizer and Blackmailer
  • Improve chat spam system (ChatManager.cs)
  • Provided role: Inspector (Inspector)
  • Using Mini.RegionInstall to add modded server regions

TOU-R

  • Host icon during the meeting
  • Changer Role Basis (RoleBasisChanger.cs)

Legal License Notice

This project utilizes a third-party API, custom-coded by The Enhanced Network. founded by Moe Wehbeh, which is not subject to the GPL 3.0 license. However, please be aware that the project itself, including any modifications, additions, or integrations made to interact with the API, is governed by the terms of the GNU General Public License version 3.0 (GPL-3.0).

Licensing Information

This project is licensed under the GNU General Public License version 3.0. For more details, please refer to the LICENSE file.

Third-Party API Access

To obtain an API token for this project, you must join our Discord server and open a ticket. Follow the steps below:

  1. Join our Discord Server: https://discord.gg/tohe

  2. Open a Ticket: Once you've joined the server, open a ticket and request an API token for TOHE API. Provide any necessary information as instructed in the ticket system.

  3. Token Usage: Upon receiving the API token, follow the instructions in the documentation to configure and use the token with the project.

Note: Access to the API is subject to our terms and conditions. Failure to comply with these terms may result in revocation of API access.


townofhost-enhanced's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

townofhost-enhanced's Issues

[Bug] RoleBase OnReportDeadBody Error!

Overview

You get an error when calling a meeting caused by null reference in TOHE.ReportDeadBodyPatch.AfterReportTasks and TOHE.ReportDeadBodyPatch.Prefix

Error

Here is the error message and dump.

Error Message In Meeting

image

Error In Dump

[Info   :      TOHE] [00:47:39][ReportDeadBody]D1GQ => null
[Error  :      TOHE] [00:47:39][ReportDeadBodyPatch]System.NullReferenceException: Object reference not set to an instance of an object.
   at TOHE.ReportDeadBodyPatch.AfterReportTasks(PlayerControl player, PlayerInfo target)
   at TOHE.ReportDeadBodyPatch.Prefix(PlayerControl __instance, PlayerInfo target)

Possible Fix

I just added a few null checks to fix the errors, but I don't know if I broke anything process so y'all will have to overview it.

Fix 1 For TOHE.ReportDeadBodyPatch.AfterReportTasks

public static void AfterReportTasks(PlayerControl player, GameData.PlayerInfo target)
{
    //=============================================
    // Hereinafter, it is assumed that the button is confirmed to be pressed
    //=============================================

    Main.LastVotedPlayerInfo = null;
    Main.GuesserGuessed.Clear();
    Main.AllKillers.Clear();


    foreach (var playerStates in Main.PlayerStates.Values.ToArray())
    {
        if (target == null) return;
        playerStates.RoleClass?.OnReportDeadBody(player, target?.Object);
    }

    // Alchemist & Bloodlust
    Alchemist.OnReportDeadBodyGlobal();

    if (Aware.IsEnable) Aware.OnReportDeadBody();

    if (target != null) Sleuth.OnReportDeadBody(player, target?.Object);



    foreach (var pc in Main.AllPlayerControls)
    {
        if (target == null) return;
        if (!Doppelganger.CheckDoppelVictim(pc.PlayerId) && !Murderer.CheckMurdererVictim(target.PlayerId))
        {
            // Update skins again, since players have different skins
            // And can be easily distinguished from each other
            if (Camouflage.IsCamouflage && Options.KPDCamouflageMode.GetValue() is 2 or 3)
            {
                Camouflage.RpcSetSkin(pc);
            }

            // Check shapeshift and revert skin to default
            if (Main.CheckShapeshift.ContainsKey(pc.PlayerId))
            {
                Camouflage.RpcSetSkin(pc, RevertToDefault: true);
            }
        }

        Logger.Info($"Player {pc?.Data?.PlayerName}: Id {pc.PlayerId} - is alive: {pc.IsAlive()}", "CheckIsAlive");
    }

    // Set meeting time
    MeetingTimeManager.OnReportDeadBody();

    // Clear all Notice players
    NameNotifyManager.Reset();

    // Update Notify Roles for Meeting
    Utils.DoNotifyRoles(isForMeeting: true, NoCache: true, CamouflageIsForMeeting: true);

    // Sync all settings on meeting start
    _ = new LateTask(Utils.SyncAllSettings, 3f, "Sync all settings after report");
}

Fix 2 For TOHE.ReportDeadBodyPatch.Prefix

class ReportDeadBodyPatch
{
    public static Dictionary<byte, bool> CanReport;
    public static Dictionary<byte, List<GameData.PlayerInfo>> WaitReport = [];
    public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] GameData.PlayerInfo target)
    {
        if (GameStates.IsMeeting || GameStates.IsHideNSeek) return false;

        if (target != null && EAC.RpcReportDeadBodyCheck(__instance, target))
        {
            Logger.Fatal("Eac patched the report body rpc", "ReportDeadBodyPatch");
            return false;
        }
        if (Options.DisableMeeting.GetBool()) return false;
        if (Options.CurrentGameMode == CustomGameMode.FFA) return false;

        if (!CanReport[__instance.PlayerId])
        {
            if (target == null) return true;
            WaitReport[__instance.PlayerId].Add(target);
            Logger.Warn($"{__instance.GetNameWithRole().RemoveHtmlTags()} : Reporting is prohibited and will wait until it becomes possible", "ReportDeadBody");
            return false;
        }

        Logger.Info($"{__instance.GetNameWithRole().RemoveHtmlTags()} => {target?.Object?.GetNameWithRole().RemoveHtmlTags() ?? "null"}", "ReportDeadBody");

        foreach (var kvp in Main.PlayerStates)
        {
            var pc = Utils.GetPlayerById(kvp.Key);
            kvp.Value.LastRoom = pc.GetPlainShipRoom();
        }

        if (!AmongUsClient.Instance.AmHost) return true;

        try
        {
            // If the player is dead, the meeting is canceled
            if (__instance.Data.IsDead) return false;

            //=============================================
            //Below, check if this meeting is allowed
            //=============================================

            var killer = target?.Object?.GetRealKiller();
            var killerRole = killer?.GetCustomRole();

            if (target == null) //Meeting
            {
                var playerRoleClass = __instance.GetRoleClass();

                if (playerRoleClass.OnCheckStartMeeting(__instance) == false)
                {
                    Logger.Info($"Player has role class: {playerRoleClass} - the start of the meeting has been cancelled", "ReportDeadBody");
                    return false;
                }
            }
            if (target != null) // Report dead body
            {
                // Guessed player cannot report
                if (Main.PlayerStates[target.PlayerId].deathReason == PlayerState.DeathReason.Gambled) return false;

                // Check report bead body
                foreach (var player in Main.PlayerStates.Values.ToArray())
                {
                    var playerRoleClass = player.RoleClass;
                    if (player == null ||  playerRoleClass == null) continue;

                    if (playerRoleClass.OnCheckReportDeadBody(__instance, target, killer) == false)
                    {
                        Logger.Info($"Player has role class: {playerRoleClass} - is canceled the report", "ReportDeadBody");
                        return false;
                    }
                }

                // if Bait is killed, check the setting condition
                if (!(target.Object.Is(CustomRoles.Bait) && Bait.BaitCanBeReportedUnderAllConditions.GetBool()))
                {
                    // Comms Camouflage
                    if (Options.DisableReportWhenCC.GetBool() && Utils.IsActive(SystemTypes.Comms) && Camouflage.IsActive) return false;
                }

                //Check unreportable bodies
                if (Main.UnreportableBodies.Contains(target.PlayerId))
                {
                    __instance.Notify(Utils.ColorString(__instance.GetRoleColor(), GetString("BodyCannotBeReported")));
                    return false;
                }

                if (target.Object.Is(CustomRoles.Unreportable)) return false;


                // 胆小鬼不敢报告
                var tpc = Utils.GetPlayerById(target.PlayerId);
                if (__instance.Is(CustomRoles.Oblivious))
                {
                    if (!tpc.Is(CustomRoles.Bait) || (tpc.Is(CustomRoles.Bait) && Oblivious.ObliviousBaitImmune.GetBool())) /* && (target?.Object != null)*/
                    {
                        return false;
                    }
                }

                var tar = Utils.GetPlayerById(target.PlayerId);

                if (__instance.Is(CustomRoles.Unlucky) && (target?.Object == null || !target.Object.Is(CustomRoles.Bait)))
                {
                    Unlucky.SuicideRand(__instance, Unlucky.StateSuicide.ReportDeadBody);
                    if (Unlucky.UnluckCheck[__instance.PlayerId]) return false;
                   
                }
            }

            if (Options.SyncButtonMode.GetBool() && target == null)
            {
                Logger.Info($"Option: {Options.SyncedButtonCount.GetInt()}, has button count: {Options.UsedButtonCount}", "ReportDeadBody");
                if (Options.SyncedButtonCount.GetFloat() <= Options.UsedButtonCount)
                {
                    Logger.Info("The button has been canceled because the maximum number of available buttons has been exceeded", "ReportDeadBody");
                    return false;
                }
                else Options.UsedButtonCount++;
                
                if (Options.SyncedButtonCount.GetFloat() == Options.UsedButtonCount)
                {
                    Logger.Info("The maximum number of meeting buttons has been reached", "ReportDeadBody");
                }
            }

            AfterReportTasks(__instance, target);

        }
        catch (Exception e)
        {
            Logger.Exception(e, "ReportDeadBodyPatch");
            Logger.SendInGame("Error: " + e.ToString());

            // If there is an error in ReportDeadBodyPatch, update the player nicknames anyway
            MeetingTimeManager.OnReportDeadBody();
            NameNotifyManager.Reset();
            Utils.DoNotifyRoles(isForMeeting: true, NoCache: true, CamouflageIsForMeeting: true);
            _ = new LateTask(Utils.SyncAllSettings, 3f, "Sync all settings after report");
        }

        return true;
    }
    public static void AfterReportTasks(PlayerControl player, GameData.PlayerInfo target)
    {
        //=============================================
        // Hereinafter, it is assumed that the button is confirmed to be pressed
        //=============================================

        Main.LastVotedPlayerInfo = null;
        Main.GuesserGuessed.Clear();
        Main.AllKillers.Clear();


        foreach (var playerStates in Main.PlayerStates.Values.ToArray())
        {
            if (target == null) return;
            playerStates.RoleClass?.OnReportDeadBody(player, target?.Object);
        }

        // Alchemist & Bloodlust
        Alchemist.OnReportDeadBodyGlobal();

        if (Aware.IsEnable) Aware.OnReportDeadBody();

        if (target != null) Sleuth.OnReportDeadBody(player, target?.Object);



        foreach (var pc in Main.AllPlayerControls)
        {
            if (target == null) return;
            if (!Doppelganger.CheckDoppelVictim(pc.PlayerId) && !Murderer.CheckMurdererVictim(target.PlayerId))
            {
                // Update skins again, since players have different skins
                // And can be easily distinguished from each other
                if (Camouflage.IsCamouflage && Options.KPDCamouflageMode.GetValue() is 2 or 3)
                {
                    Camouflage.RpcSetSkin(pc);
                }

                // Check shapeshift and revert skin to default
                if (Main.CheckShapeshift.ContainsKey(pc.PlayerId))
                {
                    Camouflage.RpcSetSkin(pc, RevertToDefault: true);
                }
            }

            Logger.Info($"Player {pc?.Data?.PlayerName}: Id {pc.PlayerId} - is alive: {pc.IsAlive()}", "CheckIsAlive");
        }

        // Set meeting time
        MeetingTimeManager.OnReportDeadBody();

        // Clear all Notice players
        NameNotifyManager.Reset();

        // Update Notify Roles for Meeting
        Utils.DoNotifyRoles(isForMeeting: true, NoCache: true, CamouflageIsForMeeting: true);

        // Sync all settings on meeting start
        _ = new LateTask(Utils.SyncAllSettings, 3f, "Sync all settings after report");
    }
    public static async void ChangeLocalNameAndRevert(string name, int time)
    {
        //async Taskじゃ警告出るから仕方ないよね。
        var revertName = PlayerControl.LocalPlayer.name;
        PlayerControl.LocalPlayer.RpcSetNameEx(name);
        await Task.Delay(time);
        PlayerControl.LocalPlayer.RpcSetNameEx(revertName);
    }
}

Role Assignment Algorithms

Would you possibly be able to help me with how the different role assignment algorithms work? I cannot seem to be able to find the information on it. Below I've listed the different ones available.

Default, .net system.random, hash random, xorshift, mersenne twister

Player dosent move

Original Poster: eispfote42
Version: 1.5.2
Original Date of Issue: March 10,2024
Fix Attempted Before? No
Map: All
Reproducible? Yes
Description/Additional Notes: If I host a game,everything works,but in a round,I can move,but other player doesnt in my view.They move in their view, but the other players (including me) don't move with them.
Thats with all people I tried,my friends,randoms etc.

Want to create a bug report/issue? Follow the template below

Issue Format and Guidelines

Example:

  • Original Poster: Discord Tag (moe.dev)
  • Version: 1.2.0 (or latest)
  • Original Date of Issue: (Date) December 4, 2023
  • Logs Attached? TOHE-v1.2.0-2023-10-29_10.42.59.log
  • Fix Attempted Before? Yes/No
  • Map: All/The Skeld/Mira HQ/Polus/Airship/The Fungle
  • Reproducible? Yes/No/Have not attempted
  • Description/Additional Notes: Provide Additional Notes, such as roles possibly conflicting, time of occurrence, who was involved

Note: Not including logs or reproduction steps may result in the issue being invalidated


Join our Discord for more discussions on changes being made to the mod!

Admirer needs a buff

I don't really like the Admirer role because of it's style, I think like Werewolf's The Miracle Merchant role is a better version of the Admirer role The Miracle Merchant is the first to act every night and chooses another player to be the lucky one, who will receive one of three one-time skills: Seer's Check, Witch's Poison or Guard's Protection, limited to each game. once. If the lucky person is a werewolf, he will not gain skills and the Miracle Merchant will be eliminated the next day


Host message in chat issue

Hi,

In Among Us v2023.10.24s (build 3653), with TOHE v1.1.1, Host can't send message into chat while others players can. And if player with TOHE v1.1.1 join the game, he will had the same issue.

Is there a fix ? Or it's due to new update ?

TaskBar parameter changes before launching the game

We used the mod in a game, we put the TaskBar setting on "Meetings" and noticed that, at the end of the countdown before launching the game, this parameter changes to "never".
The same happens when with "always" and "never" stays as is.

Add MoreGamemodes proximity chat

I was already talking about this in discords dev chat
Basically add the options for proximity chat from MoreGamemodes

the chat looks like this:
Captura de Tela (248)

Tasks:

  • [ Add Base of Proximity Chat ]

  • [ Fix errors(Like a spam of errors that happens when the match starts, making the mod completely glitch) ]

  • [ Fix a Bug that thew messages doesnt appear as expected (it appears normally on chat or it doesnt appear on name) ]

  • [ When adding it, fix a supposed bug with arrows (BloundHound and others) (thanks ryuk btw) ]

Taskinator makes everyone doing the target task crash

Version : 1.3.0
Map : Polus
Task : Ship keys & Admin card

What happened :
The game started, the taskinator did the task then me, then crash :)
Same behaviour for card. This time, multiple players has been kicked.

Canary Prep

No more roles until canary and stable are out.

Prepare for Canary & Stable

All PRs for roles/addons will be marked as Draft and In Progress

You can still put out a PR for one if you have it, but do not merge, and put the appropriate markings

[Bug] for RoleBase Branch, ReportDeadBodyPatch returns null references.

Overview

You get an error when calling a meeting caused by null reference in TOHE.ReportDeadBodyPatch.AfterReportTasks and TOHE.ReportDeadBodyPatch.Prefix

Error

Here is the error message and dump.

Error Message In Meeting

image

Error In Dump

[Info   :      TOHE] [00:47:39][ReportDeadBody]D1GQ => null
[Error  :      TOHE] [00:47:39][ReportDeadBodyPatch]System.NullReferenceException: Object reference not set to an instance of an object.
   at TOHE.ReportDeadBodyPatch.AfterReportTasks(PlayerControl player, PlayerInfo target)
   at TOHE.ReportDeadBodyPatch.Prefix(PlayerControl __instance, PlayerInfo target)

Possible Fix

I just added a few null checks to fix the errors, but I don't know if I broke anything process so y'all will have to overview it.

Fix 1 For TOHE.ReportDeadBodyPatch.AfterReportTasks

public static void AfterReportTasks(PlayerControl player, GameData.PlayerInfo target)
{
    //=============================================
    // Hereinafter, it is assumed that the button is confirmed to be pressed
    //=============================================

    Main.LastVotedPlayerInfo = null;
    Main.GuesserGuessed.Clear();
    Main.AllKillers.Clear();


    foreach (var playerStates in Main.PlayerStates.Values.ToArray())
    {
        if (target == null) return;
        playerStates.RoleClass?.OnReportDeadBody(player, target?.Object);
    }

    // Alchemist & Bloodlust
    Alchemist.OnReportDeadBodyGlobal();

    if (Aware.IsEnable) Aware.OnReportDeadBody();

    if (target != null) Sleuth.OnReportDeadBody(player, target?.Object);



    foreach (var pc in Main.AllPlayerControls)
    {
        if (target == null) return;
        if (!Doppelganger.CheckDoppelVictim(pc.PlayerId) && !Murderer.CheckMurdererVictim(target.PlayerId))
        {
            // Update skins again, since players have different skins
            // And can be easily distinguished from each other
            if (Camouflage.IsCamouflage && Options.KPDCamouflageMode.GetValue() is 2 or 3)
            {
                Camouflage.RpcSetSkin(pc);
            }

            // Check shapeshift and revert skin to default
            if (Main.CheckShapeshift.ContainsKey(pc.PlayerId))
            {
                Camouflage.RpcSetSkin(pc, RevertToDefault: true);
            }
        }

        Logger.Info($"Player {pc?.Data?.PlayerName}: Id {pc.PlayerId} - is alive: {pc.IsAlive()}", "CheckIsAlive");
    }

    // Set meeting time
    MeetingTimeManager.OnReportDeadBody();

    // Clear all Notice players
    NameNotifyManager.Reset();

    // Update Notify Roles for Meeting
    Utils.DoNotifyRoles(isForMeeting: true, NoCache: true, CamouflageIsForMeeting: true);

    // Sync all settings on meeting start
    _ = new LateTask(Utils.SyncAllSettings, 3f, "Sync all settings after report");
}

Fix 2 For TOHE.ReportDeadBodyPatch.Prefix

class ReportDeadBodyPatch
{
    public static Dictionary<byte, bool> CanReport;
    public static Dictionary<byte, List<GameData.PlayerInfo>> WaitReport = [];
    public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] GameData.PlayerInfo target)
    {
        if (GameStates.IsMeeting || GameStates.IsHideNSeek) return false;

        if (target != null && EAC.RpcReportDeadBodyCheck(__instance, target))
        {
            Logger.Fatal("Eac patched the report body rpc", "ReportDeadBodyPatch");
            return false;
        }
        if (Options.DisableMeeting.GetBool()) return false;
        if (Options.CurrentGameMode == CustomGameMode.FFA) return false;

        if (!CanReport[__instance.PlayerId])
        {
            if (target == null) return true;
            WaitReport[__instance.PlayerId].Add(target);
            Logger.Warn($"{__instance.GetNameWithRole().RemoveHtmlTags()} : Reporting is prohibited and will wait until it becomes possible", "ReportDeadBody");
            return false;
        }

        Logger.Info($"{__instance.GetNameWithRole().RemoveHtmlTags()} => {target?.Object?.GetNameWithRole().RemoveHtmlTags() ?? "null"}", "ReportDeadBody");

        foreach (var kvp in Main.PlayerStates)
        {
            var pc = Utils.GetPlayerById(kvp.Key);
            kvp.Value.LastRoom = pc.GetPlainShipRoom();
        }

        if (!AmongUsClient.Instance.AmHost) return true;

        try
        {
            // If the player is dead, the meeting is canceled
            if (__instance.Data.IsDead) return false;

            //=============================================
            //Below, check if this meeting is allowed
            //=============================================

            var killer = target?.Object?.GetRealKiller();
            var killerRole = killer?.GetCustomRole();

            if (target == null) //Meeting
            {
                var playerRoleClass = __instance.GetRoleClass();

                if (playerRoleClass.OnCheckStartMeeting(__instance) == false)
                {
                    Logger.Info($"Player has role class: {playerRoleClass} - the start of the meeting has been cancelled", "ReportDeadBody");
                    return false;
                }
            }
            if (target != null) // Report dead body
            {
                // Guessed player cannot report
                if (Main.PlayerStates[target.PlayerId].deathReason == PlayerState.DeathReason.Gambled) return false;

                // Check report bead body
                foreach (var player in Main.PlayerStates.Values.ToArray())
                {
                    var playerRoleClass = player.RoleClass;
                    if (player == null ||  playerRoleClass == null) continue;

                    if (playerRoleClass.OnCheckReportDeadBody(__instance, target, killer) == false)
                    {
                        Logger.Info($"Player has role class: {playerRoleClass} - is canceled the report", "ReportDeadBody");
                        return false;
                    }
                }

                // if Bait is killed, check the setting condition
                if (!(target.Object.Is(CustomRoles.Bait) && Bait.BaitCanBeReportedUnderAllConditions.GetBool()))
                {
                    // Comms Camouflage
                    if (Options.DisableReportWhenCC.GetBool() && Utils.IsActive(SystemTypes.Comms) && Camouflage.IsActive) return false;
                }

                //Check unreportable bodies
                if (Main.UnreportableBodies.Contains(target.PlayerId))
                {
                    __instance.Notify(Utils.ColorString(__instance.GetRoleColor(), GetString("BodyCannotBeReported")));
                    return false;
                }

                if (target.Object.Is(CustomRoles.Unreportable)) return false;


                // 胆小鬼不敢报告
                var tpc = Utils.GetPlayerById(target.PlayerId);
                if (__instance.Is(CustomRoles.Oblivious))
                {
                    if (!tpc.Is(CustomRoles.Bait) || (tpc.Is(CustomRoles.Bait) && Oblivious.ObliviousBaitImmune.GetBool())) /* && (target?.Object != null)*/
                    {
                        return false;
                    }
                }

                var tar = Utils.GetPlayerById(target.PlayerId);

                if (__instance.Is(CustomRoles.Unlucky) && (target?.Object == null || !target.Object.Is(CustomRoles.Bait)))
                {
                    Unlucky.SuicideRand(__instance, Unlucky.StateSuicide.ReportDeadBody);
                    if (Unlucky.UnluckCheck[__instance.PlayerId]) return false;
                   
                }
            }

            if (Options.SyncButtonMode.GetBool() && target == null)
            {
                Logger.Info($"Option: {Options.SyncedButtonCount.GetInt()}, has button count: {Options.UsedButtonCount}", "ReportDeadBody");
                if (Options.SyncedButtonCount.GetFloat() <= Options.UsedButtonCount)
                {
                    Logger.Info("The button has been canceled because the maximum number of available buttons has been exceeded", "ReportDeadBody");
                    return false;
                }
                else Options.UsedButtonCount++;
                
                if (Options.SyncedButtonCount.GetFloat() == Options.UsedButtonCount)
                {
                    Logger.Info("The maximum number of meeting buttons has been reached", "ReportDeadBody");
                }
            }

            AfterReportTasks(__instance, target);

        }
        catch (Exception e)
        {
            Logger.Exception(e, "ReportDeadBodyPatch");
            Logger.SendInGame("Error: " + e.ToString());

            // If there is an error in ReportDeadBodyPatch, update the player nicknames anyway
            MeetingTimeManager.OnReportDeadBody();
            NameNotifyManager.Reset();
            Utils.DoNotifyRoles(isForMeeting: true, NoCache: true, CamouflageIsForMeeting: true);
            _ = new LateTask(Utils.SyncAllSettings, 3f, "Sync all settings after report");
        }

        return true;
    }
    public static void AfterReportTasks(PlayerControl player, GameData.PlayerInfo target)
    {
        //=============================================
        // Hereinafter, it is assumed that the button is confirmed to be pressed
        //=============================================

        Main.LastVotedPlayerInfo = null;
        Main.GuesserGuessed.Clear();
        Main.AllKillers.Clear();


        foreach (var playerStates in Main.PlayerStates.Values.ToArray())
        {
            if (target == null) return;
            playerStates.RoleClass?.OnReportDeadBody(player, target?.Object);
        }

        // Alchemist & Bloodlust
        Alchemist.OnReportDeadBodyGlobal();

        if (Aware.IsEnable) Aware.OnReportDeadBody();

        if (target != null) Sleuth.OnReportDeadBody(player, target?.Object);



        foreach (var pc in Main.AllPlayerControls)
        {
            if (target == null) return;
            if (!Doppelganger.CheckDoppelVictim(pc.PlayerId) && !Murderer.CheckMurdererVictim(target.PlayerId))
            {
                // Update skins again, since players have different skins
                // And can be easily distinguished from each other
                if (Camouflage.IsCamouflage && Options.KPDCamouflageMode.GetValue() is 2 or 3)
                {
                    Camouflage.RpcSetSkin(pc);
                }

                // Check shapeshift and revert skin to default
                if (Main.CheckShapeshift.ContainsKey(pc.PlayerId))
                {
                    Camouflage.RpcSetSkin(pc, RevertToDefault: true);
                }
            }

            Logger.Info($"Player {pc?.Data?.PlayerName}: Id {pc.PlayerId} - is alive: {pc.IsAlive()}", "CheckIsAlive");
        }

        // Set meeting time
        MeetingTimeManager.OnReportDeadBody();

        // Clear all Notice players
        NameNotifyManager.Reset();

        // Update Notify Roles for Meeting
        Utils.DoNotifyRoles(isForMeeting: true, NoCache: true, CamouflageIsForMeeting: true);

        // Sync all settings on meeting start
        _ = new LateTask(Utils.SyncAllSettings, 3f, "Sync all settings after report");
    }
    public static async void ChangeLocalNameAndRevert(string name, int time)
    {
        //async Taskじゃ警告出るから仕方ないよね。
        var revertName = PlayerControl.LocalPlayer.name;
        PlayerControl.LocalPlayer.RpcSetNameEx(name);
        await Task.Delay(time);
        PlayerControl.LocalPlayer.RpcSetNameEx(revertName);
    }
}

Cannot host games

When I try to TOHE host a game, the screen remains black for a long time and then I get the message that my account cannot be authenticated.

If it doesn't do that, then I am getting this notification
image

How do I correct this issue?

Modded SA logs me off

Whenever i try to create a lobby in the Modded SA region, my account gets logged off

Ask : Does colors change roles beheviour ?

Hi,

I would ask you if there is some problem with colors roles.
We updated colors to have only 4 colors :

  • crewmates (light blue)
  • neutrals (light gray)
  • impostors (red)
  • add-ons (yellow)
  • seller (green)

But since, we've got few bugs :

  • Transporter : teleported me inside walls on Polus
  • Enigma : infos was wrong (number guess & wrong roles)
  • Sheriff : click on kill button -> Sheriff die
  • Counterfeiter : kill impostors and let crew alive
  • Jester : Has been voted but doesn't won the game

Thank you !

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.