Compare commits

..
24 Commits
Author SHA1 Message Date
Crowdin Bot 6a9e5556c1 chore: update translations for release 7.9.0 2026-08-03 08:22:19 +00:00
Gurge44 750cfb2eb8 a 2026-08-03 10:18:08 +02:00
Gurge44 02829f6480 upd chl 2026-08-03 09:31:58 +02:00
Gurge44 6ca5608b88 e 2026-08-03 09:30:14 +02:00
Gurge44 24cd080d8c Merge remote-tracking branch 'origin/main' 2026-08-03 09:28:52 +02:00
Gurge44 141c11dafa fix kick (yes, literally) 2026-08-03 09:28:41 +02:00
df2f9818e4 Add Vitals to Fox (#666)
* Update ChatCommandPatch.cs

* Update RPC.cs

* BAU support

* more flags

* revert unnecessary chatcommandpatch changes

* add setting to add Vitals to Fox

---------

Co-authored-by: lime1 <lime1@LIMEMACHINE>
Co-authored-by: Gurge44 <90392754+Gurge44@users.noreply.github.com>
2026-08-02 10:46:26 +02:00
ZypherusKhan 5d53d40087 Reorganize community health files and add contribution policies (#665)
* Add AI Policy

* Add PULL_REQUEST_TEMPLATE

* Move to .github
2026-08-01 18:26:28 +02:00
Gurge44 4368635cf2 eh 2026-08-01 13:34:17 +02:00
Gurge44 c7687411e1 changelog 2026-08-01 12:48:56 +02:00
Gurge44 2edad25e6a some more features 2026-08-01 12:20:08 +02:00
Gurge44 82241231b6 rename SNS seeker to Disguiser 2026-08-01 11:17:45 +02:00
Gurge44 946a4164e2 SNS Seeker role to Custom HNS 2026-07-31 16:29:30 +02:00
Gurge44 cfe9f85181 del 2026-07-31 15:20:08 +02:00
Gurge44 b3d9c592db Merge remote-tracking branch 'origin/main' 2026-07-31 15:03:21 +02:00
Gurge44 e1c21be60e fixes & optimizations 2026-07-31 15:03:12 +02:00
ZypherusKhan 0764886b96 Fix Startup Crash and Map Icon Patches (#658)
* Fix log error on Starlight

* Refactor map icon patches
2026-07-31 15:03:01 +02:00
Gurge44 4bed4f6d0e fix kick after voting ends 2026-07-31 11:32:29 +02:00
limeau (via Bot) cb304028be Add EAC entry: 800955a89 2026-07-28 17:09:27 +00:00
Gurge44 21310dc2dd bruh commit pls 2026-07-22 19:49:18 +02:00
Gurge44 4f009766d0 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	packaging-steam/BepInEx/config/BepInEx.cfg
2026-07-22 19:08:22 +02:00
Gurge44 8583fdb974 fix cfg 2026-07-22 19:07:34 +02:00
Gurge44 7af710d449 x64 doorstop 2026-07-22 19:00:36 +02:00
Gurge44 ecab516452 Add Credits 2026-07-22 07:57:51 +02:00
59 changed files with 30796 additions and 19822 deletions

No files matched your search

+3
View File
@@ -197,6 +197,9 @@ resharper_web_config_module_not_resolved_highlighting = warning
resharper_web_config_type_not_resolved_highlighting = warning
resharper_web_config_wrong_module_highlighting = warning
dotnet_diagnostic.CA2211.severity = none
[*.{cs,vb}]
#### Naming styles ####
+54
View File
@@ -0,0 +1,54 @@
# AI Policy
Using AI (i.e., LLMs) as tools for coding is welcome. A high bar is held for
all contributions to this project. Moreover, the project maintainers remain
responsible for any code that is published as part of a release. Contributors
are expected to be responsible for any code they publish.
**If you use AI in any part of your contribution, you must declare it.** This
includes the model and version used (e.g. GPT-5, Claude Sonnet 4.5, Gemini 3.0
Flash). Claiming authorship of AI-generated code is inaccurate if your role was
to prompt an AI and paste the result. Ownership implies understanding; if you
cannot explain what the code does, you did not write it.
**If you do not understand the code you are submitting, do not submit it.** This
applies specifically to AI-generated code that you have copy-pasted without
reading or understanding. If you find yourself hoping it works rather than
knowing it works, that is a signal to stop. Open a suggestion or discussion
instead. Describe what you want to achieve, and let a maintainer or contributor
who understands the codebase implement it. A suggestion from someone unfamiliar
with the code is valuable. A pull request from them is a liability.
This project requires a human in the loop who understands the work produced by
AI. **Autonomous agents are not allowed to be used for contributing to this
project**. Pull requests that appear in violation of this will be closed,
perhaps without notice.
**AI should not be used to generate comments when communicating with
maintainers**. Comments are expected to be written by humans. Comments that are
believed to be written by AI may be hidden without notice.
If you are opening an issue, you should be able to describe the problem in your
own words.
If you are opening a pull request, you are expected to be able to explain the
proposed changes in your own words. This includes the pull request body and
responses to questions. **Do not copy responses from the AI when replying to
questions from maintainers.**
If you wish to include context from an interaction with AI in your comments, it
must be in a quote block (e.g., using `>`) and disclosed as such. It must be
accompanied by human commentary explaining the relevance and implications of
the context. Do not share long snippets.
AI is useful when communicating as a non-native English speaker. If you are
using AI to edit your comments for this purpose, please take the time to ensure
it reflects your own voice and ideas. If using AI for translation, we recommend
writing in your native language and including the AI translation in a quote
block.
Senior contributors and maintainers may exercise discretion in how strictly
these guidelines apply to their own workflow, as their track record and
familiarity with the codebase speak for themselves.
This policy was adapted from [uv's AI policy](https://github.com/astral-sh/.github/blob/main/AI_POLICY.md) and further modified by @ZypherusKhan.
File renamed without changes.
+5 -1
View File
@@ -27,7 +27,11 @@ You don’t need to get approval for every small fix or improvement, as long as
- Follow the **existing code style**.
- JetBrains Rider is recommended, as the editor settings are included in the repo, so they will sync automatically if used by contributors.
- Make sure your changes are consistent with the surrounding code.
- Make sure your changes are consistent with the surrounding code.
### Use of AI
All use of AI in contributions must follow our [AI Policy](./AI_POLICY.md). Contributions that do not comply will be closed.
---
+49
View File
@@ -0,0 +1,49 @@
# Summary
<!--- Provide a general summary of your changes -->
## What type of PR is this? (check all that apply)
<!--- Put an `x` in the boxes that apply, e.g. - [x] Bug Fix -->
- [ ] Bug Fix
- [ ] New Feature
- [ ] Refactor / Optimization
- [ ] Documentation Update
- [ ] Other
## Description
<!---
Describe your changes in detail. What did you change and why?
Be specific enough that a reviewer can understand without running the code.
-->
## Related issue or discussion
<!---
Link any related issue, suggestion, or discussion below.
If this was discussed or suggested on Discord, include a link or brief description of the relevant message or thread.
-->
## Screenshots / Videos
<!---
If your change affects anything visual or gameplay-related, attach screenshots or a short video.
Not required for pure refactors or translation updates.
-->
## Checklist
<!--- Put an `x` in the boxes that apply, e.g. - [x] I have read CONTRIBUTING.md -->
- [ ] I have read [CONTRIBUTING.md](./CONTRIBUTING.md) and my changes follow its guidelines
- [ ] I have read the [AI Policy](./AI_POLICY.md) and I am complying with it
- [ ] I have performed a self-review of my own code and it follows the code style of this project
- [ ] I understand every part of the code I am submitting and can explain it if asked
- [ ] I have commented my code where the logic is not immediately obvious
- [ ] I have tested my changes in-game and they work as expected
- [ ] My changes do not break any existing functionality I am aware of
- [ ] I have not left behind debug code, commented-out blocks, or unnecessary logging
- [ ] I added or updated translation keys if applicable
- [ ] If this adds a new role, add-on, game mode, or option, it is properly registered
## AI usage declaration
<!---
Write "None" if you did not use AI. If you did, declare what you used it for.
The AI Policy you agreed to above covers the rest.
-->
View File
File renamed without changes.
View File
File renamed without changes.
+2 -2
View File
@@ -198,8 +198,8 @@ jobs:
- name: Copy packaging files to BepInEx config
run: |
cp -rf packaging/* epic/
cp -rf packaging/* steam/
cp -rf packaging-epic/* epic/
cp -rf packaging-steam/* steam/
- name: Steam App ID
run : echo "945360" > steam/steam_appid.txt
@@ -1,252 +0,0 @@
name: Build & Release EHR Without Crowdin Updates
on:
workflow_dispatch:
inputs:
version:
description: "Version (e.g. 7.0.2)"
required: true
jobs:
# ---------------------------------------------------------
# 1) Build EHR on Linux
# ---------------------------------------------------------
build-ehr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 6.0.x
- name: Build EHR
run: dotnet build EHR.csproj -c Release -o build/
- name: Upload EHR artifact
uses: actions/upload-artifact@v4
with:
name: ehr
path: build/EHR.dll
# ---------------------------------------------------------
# 2) Build Control Panel on Windows using MSBuild
# ---------------------------------------------------------
build-control-panel:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 6.0.x
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2
- name: Restore .NET packages
run: dotnet restore -p:SelfContained=true CTA/CustomTeamAssigner/CustomTeamAssigner.csproj
- name: Build Control Panel (MSBuild)
run: |
msbuild CTA/CustomTeamAssigner/CustomTeamAssigner.csproj `
/p:Configuration=Release `
/p:Platform="x64" `
/p:PublishSingleFile=true `
/p:SelfContained=true `
/p:RuntimeIdentifier=win-x64 `
/p:IncludeAllContentForSelfExtract=true `
/p:DebugType=None `
/p:PublishDir=build\ `
/t:publish
- name: Rename exe file
run: |
mkdir build/
mv CTA/CustomTeamAssigner/build/CustomTeamAssigner.exe build/EHR_Control-Panel_BETA.exe
- name: Upload Control Panel artifact
uses: actions/upload-artifact@v4
with:
name: control-panel
path: build\EHR_Control-Panel_BETA.exe
# ---------------------------------------------------------
# 3) Sign binaries using SignPath
# ---------------------------------------------------------
sign:
runs-on: ubuntu-latest
needs: [build-ehr, build-control-panel]
steps:
- name: Download EHR
uses: actions/download-artifact@v4
with:
name: ehr
path: signing
- name: Download Control Panel
uses: actions/download-artifact@v4
with:
name: control-panel
path: signing
- name: Create SignPath ZIP
run: |
cd signing
zip ../signpath-input.zip EHR.dll EHR_Control-Panel_BETA.exe
- name: Upload unsigned artifact
id: upload-unsigned-artifact
uses: actions/upload-artifact@v4
with:
name: signpath-input
path: signpath-input.zip
- name: Submit signing request
uses: signpath/github-action-submit-signing-request@v2
with:
api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
organization-id: 298f5e96-d02b-40b5-88f6-32bddafcd47d
project-slug: EndlessHostRoles
signing-policy-slug: test-signing
artifact-configuration-slug: initial
github-artifact-id: ${{ steps.upload-unsigned-artifact.outputs.artifact-id }}
wait-for-completion: true
output-artifact-directory: signed
- name: Extract signed ZIP
run: |
mkdir extracted
unzip signed/*.zip -d extracted
- name: Upload signed binaries
uses: actions/upload-artifact@v4
with:
name: signed-binaries
path: extracted/*
# ---------------------------------------------------------
# 4) Package everything on Linux
# ---------------------------------------------------------
package:
runs-on: ubuntu-latest
needs: [sign]
steps:
- uses: actions/checkout@v4
- name: Download signed binaries
uses: actions/download-artifact@v4
with:
name: signed-binaries
path: artifacts/signed
- 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-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/signed/EHR.dll epic/BepInEx/plugins/
cp artifacts/signed/EHR.dll steam/BepInEx/plugins/
- name: Download modded regions 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: Copy packaging files to BepInEx config
run: |
cp -r packaging/* epic/
cp -r packaging/* steam/
- name: Steam App ID
run : echo "945360" > steam/steam_appid.txt
- name: Create Epic/MS Store ZIP
run: |
cd epic
zip -r "../EHR.v${{ github.event.inputs.version }}_Epic-Games_Microsoft-Store.zip" .
- name: Create Steam ZIP
run: |
cd steam
zip -r "../EHR.v${{ github.event.inputs.version }}_Steam.zip" .
- name: Upload release artifacts
uses: actions/upload-artifact@v4
with:
name: final-zips
path: ./EHR*.zip
# ---------------------------------------------------------
# 5) Create GitHub Release
# ---------------------------------------------------------
release:
runs-on: ubuntu-latest
needs: [package]
steps:
- uses: actions/checkout@v4
# -----------------------------
# Download all artifacts
# -----------------------------
- name: Download packaged ZIPs
uses: actions/download-artifact@v4
with:
name: final-zips
path: release-artifacts/zips
- name: Download signed binaries
uses: actions/download-artifact@v4
with:
name: signed-binaries
path: release-artifacts/signed
# -----------------------------
# Create GitHub Release
# -----------------------------
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: "v${{ github.event.inputs.version }}"
name: "EHR v${{ github.event.inputs.version }}"
generate_release_notes: true
body_path: CHANGELOG.md
files: |
release-artifacts/zips/*
release-artifacts/signed/EHR.dll
release-artifacts/signed/*.exe
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# -----------------------------
# Send Mod News
# -----------------------------
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: 3.x
- name: Install dependencies
run: pip install requests markdown
- name: Run script and send ModNews
env:
MODNEWS_API_URL: ${{ secrets.MODNEWS_API_URL }}
MODNEWS_API_TOKEN: ${{ secrets.MODNEWS_API_TOKEN }}
run: python release_to_modnews.py
-130
View File
@@ -1,130 +0,0 @@
name: Test Artifact Signing
on:
workflow_dispatch:
inputs:
version:
description: "Version (e.g. 7.0.2)"
required: true
jobs:
# ---------------------------------------------------------
# 1) Build EHR on Linux
# ---------------------------------------------------------
build-ehr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 6.0.x
- name: Build EHR
run: dotnet build EHR.csproj -c Release -o build/
- name: Upload EHR artifact
uses: actions/upload-artifact@v4
with:
name: ehr
path: build/EHR.dll
# ---------------------------------------------------------
# 2) Build Control Panel on Windows using MSBuild
# ---------------------------------------------------------
build-control-panel:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 6.0.x
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2
- name: Restore .NET packages
run: dotnet restore -p:SelfContained=true CTA/CustomTeamAssigner/CustomTeamAssigner.csproj
- name: Build Control Panel (MSBuild)
run: |
msbuild CTA/CustomTeamAssigner/CustomTeamAssigner.csproj `
/p:Configuration=Release `
/p:Platform="x64" `
/p:PublishSingleFile=true `
/p:SelfContained=true `
/p:RuntimeIdentifier=win-x64 `
/p:IncludeAllContentForSelfExtract=true `
/p:DebugType=None `
/p:PublishDir=build\ `
/t:publish
- name: Rename exe file
run: |
mkdir build/
mv CTA/CustomTeamAssigner/build/CustomTeamAssigner.exe build/EHR_Control-Panel_BETA.exe
- name: Upload Control Panel artifact
uses: actions/upload-artifact@v4
with:
name: control-panel
path: build\EHR_Control-Panel_BETA.exe
# ---------------------------------------------------------
# 3) Sign binaries using SignPath
# ---------------------------------------------------------
sign:
runs-on: ubuntu-latest
needs: [build-ehr, build-control-panel]
steps:
- name: Download EHR
uses: actions/download-artifact@v4
with:
name: ehr
path: signing
- name: Download Control Panel
uses: actions/download-artifact@v4
with:
name: control-panel
path: signing
- name: Create SignPath ZIP
run: |
cd signing
zip ../signpath-input.zip EHR.dll EHR_Control-Panel_BETA.exe
- name: Upload unsigned artifact
id: upload-unsigned-artifact
uses: actions/upload-artifact@v4
with:
name: signpath-input
path: signpath-input.zip
- name: Submit signing request
uses: signpath/github-action-submit-signing-request@v2
with:
api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
organization-id: 298f5e96-d02b-40b5-88f6-32bddafcd47d
project-slug: EndlessHostRoles
signing-policy-slug: test-signing
artifact-configuration-slug: initial
github-artifact-id: ${{ steps.upload-unsigned-artifact.outputs.artifact-id }}
wait-for-completion: true
output-artifact-directory: signed
- name: Extract signed ZIP
run: |
mkdir extracted
unzip signed/*.zip -d extracted
- name: Upload signed binaries
uses: actions/upload-artifact@v4
with:
name: signed-binaries
path: extracted/*
+11 -21
View File
@@ -1,28 +1,18 @@
# Thank you so much for finding and using EHR!
# FULL MANUAL REINSTALLATION REQUIRED!!
> [!CAUTION]
> **YOU MUST FULLY REINSTALL THE MOD FOR THIS UPDATE TO WORK!!!!** Just replacing EHR.dll does NOT fix the issues!
### This release fixes the crashes introduced by the latest Among Us update.
#### The necessary changes are NOT in EHR.dll, hence why you need to completely reinstall the mod for the fixes to take effect.
Shoutout to Pietro for finding the reason and the fix!
> [!IMPORTANT]
> Make sure to back up your templates, player data, banlist, presets, etc. before you reinstall! We're happy to assist you in our Discord server.
##### Other changes
- Optimizations, both FPS-wise and network-wise
- New add-on: Focused (Killers-Only Mixed)
- New setting: `Enable use of /anagram` (Mod Settings > Commands)
- Added non-host modded client sync for Committed, Haunter, Markseeker, President, and Curser
- Players can no longer use ghost roles' abilities after meetings before the cooldown is applied
- Inquisitor inspecting a neutral who only knows their own role now shows the same message as a crewmate
- New mini game mode under Custom Hide And Seek: `SHIFT AND SEEK`
- This comes with a new seeker role for the game mode called Disguiser, which has a Shapeshifter basis. It has settings to make it behave like an SNS Seeker and customize it however you want. It functions just like any other seeker role in the game mode.
- For convenience, there's a `SHIFT AND SEEK` setting in Mod Settings when the game mode is set to (Custom) Hide And Seek, which makes sure all seeker roles will be Disguiser and enables the role on 100%. Disabling this setting also sets the Disguiser role's spawn chance to 0%. You CAN still use Disguiser even if `SHIFT AND SEEK` is disabled, you just have to re-enable the role yourself. It will spawn like any other seeker role.
- This mini game mode also appears as an option in /gmpoll, which when voted, sets the game mode to (Custom) Hide And Seek, and enables the `SHIFT AND SEEK` setting mentioned above. When normal HNS gets voted, the system disables the setting.
- Fixed kicks after the voting ends on vanilla regions
- Additional optimizations
- Fixed a bug that lead to kicks with large packets
- Fixed kicks caused by chat clearing
- CHNS: Seekers are announced at the start if players can see each other's roles
- First death recording now skips disconnects
> [!WARNING]
> If you're joining a lobby hosted on vanilla regions (NA/EU/AS), please make sure you have a vanilla region selected in the Create Game menu, otherwise authentication will fail. ("Sabotage! The Among Us servers could not authenticate you!")
I'm saying this now, it's guaranteed that we'll get someone who skipped reading this complaining about this exact issue.
> If you're joining a lobby hosted on vanilla regions (NA/EU/AS), please make sure you have a vanilla region selected in the Create Game menu, otherwise authentication will fail.
> [!TIP]
> **Play on modded regions** (MEU/MAS/MNA/Niko-EU/Niko-AS/Niko-NA) for an overall better experience. Mobile and PC users can install them [from my website](https://ehr.gurge44.eu/regions).
+1
View File
@@ -473,6 +473,7 @@ public enum CustomRoles
Venter,
Agent,
Taskinator,
Disguiser,
// Speedrun
Runner,
+1
View File
@@ -473,6 +473,7 @@ public enum CustomRoles
Venter,
Agent,
Taskinator,
Disguiser,
// Speedrun
Runner,
+18 -1
View File
@@ -82,6 +82,23 @@
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Housekeeping/Layout/SolBuilderDuoView/ShowBuildProgressInToolWindow/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=98B559F14581554F8D9507F43BE0B5C5/@KeyIndexDefined">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=98B559F14581554F8D9507F43BE0B5C5/Applicability/=Live/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=98B559F14581554F8D9507F43BE0B5C5/Applicability/=Surround/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=98B559F14581554F8D9507F43BE0B5C5/Description/@EntryValue">Reformat into LateTask</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=98B559F14581554F8D9507F43BE0B5C5/Field/=DELAY/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=98B559F14581554F8D9507F43BE0B5C5/Field/=DELAY/Expression/@EntryValue">constant("0.2f")</s:String>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=98B559F14581554F8D9507F43BE0B5C5/Field/=DELAY/Order/@EntryValue">0</s:Int64>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=98B559F14581554F8D9507F43BE0B5C5/Reformat/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=98B559F14581554F8D9507F43BE0B5C5/Scope/=C3001E7C0DA78E4487072B7E050D86C5/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=98B559F14581554F8D9507F43BE0B5C5/Scope/=C3001E7C0DA78E4487072B7E050D86C5/CustomProperties/=minimumLanguageVersion/@EntryIndexedValue">2.0</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=98B559F14581554F8D9507F43BE0B5C5/Scope/=C3001E7C0DA78E4487072B7E050D86C5/Type/@EntryValue">InCSharpFile</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=98B559F14581554F8D9507F43BE0B5C5/Shortcut/@EntryValue">latetask</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=98B559F14581554F8D9507F43BE0B5C5/ShortenQualifiedReferences/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=98B559F14581554F8D9507F43BE0B5C5/Text/@EntryValue">LateTask.New(() =&gt;
{
$SELECTION$
}, $DELAY$);</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=A0247799D36DB94EBB3D0F552C99C784/@KeyIndexDefined">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=A0247799D36DB94EBB3D0F552C99C784/Applicability/=Live/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=A0247799D36DB94EBB3D0F552C99C784/Applicability/=Surround/@EntryIndexedValue">True</s:Boolean>
@@ -100,7 +117,7 @@
$SELECTION$
}
catch { }</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=DED7798D82D02045ABA68FC339C76DFA/Field/=EXCEPTION/Expression/@EntryValue">constant("System.Exception")</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=DED7798D82D02045ABA68FC339C76DFA/Field/=EXCEPTION/Expression/@EntryValue">suggestVariableType()</s:String>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=DED7798D82D02045ABA68FC339C76DFA/Field/=EXCEPTION/InitialRange/@EntryValue">-1</s:Int64>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=DED7798D82D02045ABA68FC339C76DFA/Field/=EX_005FNAME/InitialRange/@EntryValue">-1</s:Int64>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=DED7798D82D02045ABA68FC339C76DFA/Text/@EntryValue">try
+26 -8
View File
@@ -22,6 +22,7 @@ internal static class CustomHnS
private static OptionItem DangerMeter;
private static OptionItem PlayersSeeRoles;
private static OptionItem ChatDuringGame;
private static OptionItem ShiftAndSeek;
public static Dictionary<Team, Dictionary<CustomRoles, int>> HideAndSeekRoles = [];
public static Dictionary<byte, (IHideAndSeekRole Interface, CustomRoles Role)> PlayerRoles = [];
@@ -32,6 +33,7 @@ internal static class CustomHnS
public static int RandomNeutralsNum => IRandom.Instance.Next(MinNeutrals.GetInt(), MaxNeutrals.GetInt() + 1);
public static int MaximumGameLength => MaxGameLength.GetInt();
public static bool Chat => ChatDuringGame.GetBool();
public static bool SNS { get => ShiftAndSeek.GetBool(); set => ShiftAndSeek.SetValue(value ? 1 : 0); }
public static void SetupCustomOption()
{
@@ -62,6 +64,12 @@ internal static class CustomHnS
ChatDuringGame = new BooleanOptionItem(id + 5, "FFA_ChatDuringGame", false, TabGroup.GameSettings)
.SetGameMode(CustomGameMode.HideAndSeek)
.SetColor(color);
ShiftAndSeek = new BooleanOptionItem(id + 6, "HNS.ShiftAndSeek", false, TabGroup.GameSettings)
.SetGameMode(CustomGameMode.HideAndSeek)
.SetColor(color)
.RegisterUpdateValueEvent((_, _, newValue) => Options.CustomRoleSpawnChances[CustomRoles.Disguiser].SetValue(newValue * (100 / 5)))
.SetRunEventOnLoad(true);
}
public static void Init()
@@ -76,7 +84,7 @@ internal static class CustomHnS
HideAndSeekRoles = types
.Select(x => (IHideAndSeekRole)Activator.CreateInstance(x))
.Where(x => x != null)
.Join(AllHnSRoles, x => x.GetType().Name.ToLower(), x => x.ToString().ToLower(), (Interface, Enum) => (Enum, Interface))
.Join(AllHnSRoles.FindAll(role => !ShiftAndSeek.GetBool() ? (role is CustomRoles.Seeker or CustomRoles.Hider || role.GetMode() != 0) : (role == CustomRoles.Disguiser || (role is not (CustomRoles.Seeker or CustomRoles.Locator or CustomRoles.Dasher or CustomRoles.Venter or CustomRoles.Agent) && role.GetMode() != 0))), x => x.GetType().Name.ToLower(), x => x.ToString().ToLower(), (Interface, Enum) => (Enum, Interface))
.Where(x => (!x.Enum.OnlySpawnsWithPets() || Options.UsePets.GetBool()) && (x.Enum != CustomRoles.Agent || SeekerNum >= 2) && x.Interface.Count > 0 && (x.Interface.Team == Team.Neutral || x.Interface.Chance > IRandom.Instance.Next(100)))
.OrderBy(x => x.Enum is CustomRoles.Seeker or CustomRoles.Hider ? 100 : IRandom.Instance.Next(100))
.GroupBy(x => x.Interface.Team)
@@ -90,6 +98,9 @@ internal static class CustomHnS
Main.AllPlayerKillCooldown.SetAllValues(Seeker.KillCooldown.GetFloat());
IsBlindTime = true;
Utils.MarkEveryoneDirtySettingsV4();
float time = Seeker.BlindTime.GetFloat() + 14f;
if (PlayersSeeRoles.GetBool()) Main.EnumerateAlivePlayerControls().NotifyPlayers(string.Format(Translator.GetString("HNSSeekers"), string.Join(", ", PlayerRoles.Where(x => x.Value.Interface.Team == Team.Impostor).Select(x => x.Key.ColoredPlayerName()))), time + 3f, setName: false);
LateTask.New(() =>
{
@@ -102,15 +113,20 @@ internal static class CustomHnS
.Do(x => x.pc.SetKillCooldown());
LateTask.New(() => Main.Instance.StartCoroutine(Utils.NotifyEveryoneAsync(noCache: false)), 3f, log: false);
}, Seeker.BlindTime.GetFloat() + 14f, "Blind Time Expire");
}, time, "Blind Time Expire");
}
public static List<CustomRoles> GetAllHnsRoles(IEnumerable<Type> types)
public static List<CustomRoles> GetAllHnsRoles(Type[] types)
{
return types
.Select(x => Enum.Parse<CustomRoles>(ignoreCase: true, value: x.Name))
.Where(role => role is CustomRoles.Seeker or CustomRoles.Hider || role.GetMode() != 0)
.ToList();
List<CustomRoles> roles = [];
foreach (Type type in types)
{
if (Enum.TryParse(type.Name, ignoreCase: true, out CustomRoles role))
roles.Add(role);
}
return roles;
}
private static Type[] CachedHnsTypes;
@@ -145,7 +161,7 @@ internal static class CustomHnS
Dictionary<byte, CustomRoles> preSetRoles = Main.SetRoles.AddRange(ChatCommands.DraftResult, false);
if (ChatCommands.DraftResult.Count > 0 && ChatCommands.DraftResult.Count + preSetRoles.Count >= allPlayers.Count && preSetRoles.All(x => x.Value is not (CustomRoles.Seeker or CustomRoles.Locator or CustomRoles.Dasher or CustomRoles.Venter or CustomRoles.Agent)))
if (ChatCommands.DraftResult.Count > 0 && ChatCommands.DraftResult.Count + preSetRoles.Count >= allPlayers.Count && preSetRoles.All(x => x.Value is not (CustomRoles.Seeker or CustomRoles.Locator or CustomRoles.Dasher or CustomRoles.Venter or CustomRoles.Agent or CustomRoles.Disguiser)))
{
byte removeKey = ChatCommands.DraftResult.Keys.RandomElement();
ChatCommands.DraftResult.Remove(removeKey);
@@ -518,6 +534,8 @@ internal static class CustomHnS
{
if (PlayerRoles[killer.PlayerId].Interface.Team != Team.Impostor || PlayerRoles[target.PlayerId].Interface.Team == Team.Impostor || IsBlindTime) return;
if (killer.Is(CustomRoles.Disguiser) && !Disguiser.CheckMurder(killer, target)) return;
killer.Kill(target);
if (Main.GM.Value && AmongUsClient.Instance.AmHost) PlayerControl.LocalPlayer.KillFlash();
+4 -3
View File
@@ -41,8 +41,8 @@ public class Main : BasePlugin
private const string DebugKeyHash = "c0fd562955ba56af3ae20d7ec9e64c664f0facecef4b3e366e109306adeae29d";
private const string DebugKeySalt = "59687b";
public const string PluginGuid = "com.gurge44.endlesshostroles";
public const string PluginVersion = "7.8.0";
public const string PluginDisplayVersion = "7.8.0";
public const string PluginVersion = "7.9.0";
public const string PluginDisplayVersion = "7.9.0";
public const bool TestBuild = false;
public const string NeutralColor = "#ffab1b";
@@ -902,7 +902,8 @@ public class Main : BasePlugin
{ CustomRoles.Locator, "#f59e42" },
{ CustomRoles.Venter, "#694141" },
{ CustomRoles.Agent, "#ff8f8f" },
{ CustomRoles.Taskinator, "#561dd1" }
{ CustomRoles.Taskinator, "#561dd1" },
{ CustomRoles.Disguiser, "#b34646" }
};
CustomRoleValues.Where(x => x.GetCustomRoleTypes() == CustomRoleTypes.Impostor).Do(x => RoleHtmlColors.TryAdd(x, ImpostorColor));
+1 -1
View File
@@ -117,7 +117,7 @@ public static class AntiBlackout
}
catch (Exception e) { Utils.ThrowException(e); }
}
}, 0.2f, "Set Desync Roles");
}, 0.2f, "Set Desync Roles", log: false);
}
catch (Exception e) { Utils.ThrowException(e); }
}
+1 -1
View File
@@ -21,7 +21,7 @@ public static class AutoHaunt
CustomGameMode.FFA => validPCs.MaxBy(x => FreeForAll.KillCount.GetValueOrDefault(x.PlayerId, 0)),
CustomGameMode.StopAndGo => validPCs.MaxBy(x => x.GetTaskState().CompletedTasksCount),
CustomGameMode.HotPotato => HotPotato.GetState().HolderID.GetPlayer(),
CustomGameMode.HideAndSeek => validPCs.OrderByDescending(x => x.GetCustomRole() is CustomRoles.Venter or CustomRoles.Dasher).ThenByDescending(x => CustomHnS.PlayerRoles.TryGetValue(x.PlayerId, out (IHideAndSeekRole Interface, CustomRoles Role) info) && info.Interface.Team == Team.Impostor).ThenByDescending(x => CustomHnS.PlayerRoles.TryGetValue(x.PlayerId, out (IHideAndSeekRole Interface, CustomRoles Role) info) && info.Interface.Team == Team.Neutral).FirstOrDefault(),
CustomGameMode.HideAndSeek => validPCs.OrderByDescending(x => x.GetCustomRole() is CustomRoles.Venter or CustomRoles.Dasher or CustomRoles.Disguiser).ThenByDescending(x => CustomHnS.PlayerRoles.TryGetValue(x.PlayerId, out (IHideAndSeekRole Interface, CustomRoles Role) info) && info.Interface.Team == Team.Impostor).ThenByDescending(x => CustomHnS.PlayerRoles.TryGetValue(x.PlayerId, out (IHideAndSeekRole Interface, CustomRoles Role) info) && info.Interface.Team == Team.Neutral).FirstOrDefault(),
CustomGameMode.Speedrun => Speedrun.CanKill.Count > 0 ? Speedrun.CanKill.ToValidPlayers().RandomElement() : validPCs.MaxBy(x => x.GetTaskState().CompletedTasksCount),
CustomGameMode.CaptureTheFlag => validPCs.OrderByDescending(x => CaptureTheFlag.IsCarrier(x.PlayerId)).ThenByDescending(x => CaptureTheFlag.GetFlagTime(x.PlayerId)).ThenByDescending(x => CaptureTheFlag.GetTagCount(x.PlayerId)).FirstOrDefault(),
CustomGameMode.RoomRush => RoomRush.PointsSystem ? validPCs.MaxBy(x => RoomRush.GetPoints(x.PlayerId)) : validPCs.RandomElement(),
+2 -1
View File
@@ -412,7 +412,7 @@ internal static class CustomRolesHelper
// Hide And Seek
CustomRoles.Hider => CustomRoles.Crewmate,
CustomRoles.Seeker => CustomRoles.Impostor,
CustomRoles.Fox => CustomRoles.Crewmate,
CustomRoles.Fox => Fox.HasVitals.GetBool() ? CustomRoles.Scientist : CustomRoles.Crewmate,
CustomRoles.Troll => CustomRoles.Crewmate,
CustomRoles.Jumper => CustomRoles.Engineer,
CustomRoles.Detector => CustomRoles.Crewmate,
@@ -422,6 +422,7 @@ internal static class CustomRolesHelper
CustomRoles.Venter => CustomRoles.Impostor,
CustomRoles.Agent => CustomRoles.Impostor,
CustomRoles.Taskinator => CustomRoles.Crewmate,
CustomRoles.Disguiser => CustomRoles.Shapeshifter,
// Stop And Go
CustomRoles.Tasker => CustomRoles.Crewmate,
+33 -25
View File
@@ -166,36 +166,21 @@ public class CustomRpcSender
if (currentState == State.InRootPackedMessage)
{
static int GetPackedIntSize(int value)
{
uint v = (uint)value;
int count = 0;
do
{
v >>= 7;
count++;
}
while (v != 0);
return count;
}
if (3 + GetPackedIntSize(AmongUsClient.Instance.GameId) >= stream.Length)
if (stream.Length <= 11)
dispose = true;
else
EndMessage();
}
if (currentState != State.Ready)
if (!dispose && currentState != State.Ready)
{
if (currentState == State.Finished)
{
Logger.Warn($"Tried to send RPC but \"{name}\" is already Finished", "CustomRpcSender.Warn");
Logger.Warn($"Tried to send Message but \"{name}\" is already Finished", "CustomRpcSender.Warn");
return;
}
var errorMsg = $"Tried to send RPC but State is not Ready (in: \"{name}\", state: {currentState})";
var errorMsg = $"Tried to send Message but State is not Ready (in: \"{name}\", state: {currentState})";
if (isUnsafe)
Logger.Warn(errorMsg, "CustomRpcSender.Warn");
@@ -242,7 +227,7 @@ public class CustomRpcSender
{
if (currentState != State.InRpc)
{
var errorMsg = $"Tried to write RPC, but State is not InRpc (in: \"{name}\")";
var errorMsg = $"Tried to write into RPC, but State is not InRpc (in: \"{name}\")";
if (isUnsafe)
Logger.Warn(errorMsg, "CustomRpcSender.Warn");
@@ -273,7 +258,7 @@ public class CustomRpcSender
if (currentState == State.InRootPackedMessage && targetClientId < 0)
{
var errorMsg = $"Tried to start RPC, but State is InRootPackedMessage and the requested targetClientId is negative. Only GameDataTo messages can be started in this state. (in: \"{name}\")";
var errorMsg = $"Tried to start Message, but State is InRootPackedMessage and the requested targetClientId is negative. Only GameDataTo messages can be started in this state. (in: \"{name}\")";
if (isUnsafe)
Logger.Warn(errorMsg, "CustomRpcSender.Warn");
@@ -323,7 +308,7 @@ public class CustomRpcSender
{
if (currentState != State.Ready)
{
var errorMsg = $"Tried to start Message but State is not Ready (in: \"{name}\")";
var errorMsg = $"Tried to start Packed Message but State is not Ready (in: \"{name}\")";
if (isUnsafe)
Logger.Warn(errorMsg, "CustomRpcSender.Warn");
@@ -351,7 +336,7 @@ public class CustomRpcSender
{
if (currentState is not State.InRootMessage and not State.InRootPackedMessage)
{
var errorMsg = $"Tried to exit Message but State is not InRootMessage or InRootPackedMessage (in: \"{name}\")";
var errorMsg = $"Tried to end Message but State is not InRootMessage or InRootPackedMessage (in: \"{name}\")";
if (isUnsafe)
Logger.Warn(errorMsg, "CustomRpcSender.Warn");
@@ -418,8 +403,9 @@ public class CustomRpcSender
if (messages >= AmongUsClient.Instance.GetMaxMessagePackingLimit())
{
int targetClientId = currentRpcTarget;
EndMessage(startNew: true);
StartMessage(currentRpcTarget);
StartMessage(targetClientId);
}
messages++;
@@ -436,7 +422,7 @@ public class CustomRpcSender
{
if (currentState != State.InRpc)
{
var errorMsg = $"Tried to terminate RPC but State is not InRpc (in: \"{name}\")";
var errorMsg = $"Tried to end RPC but State is not InRpc (in: \"{name}\")";
if (isUnsafe)
Logger.Warn(errorMsg, "CustomRpcSender.Warn");
@@ -966,6 +952,28 @@ public static class CustomRpcSenderExtensions
return true;
}
public bool RpcExitVentDesync(PlayerPhysics physics, int ventId, PlayerControl seer)
{
if (!physics) return false;
int clientId = seer.OwnerId;
if (AmongUsClient.Instance.ClientId == clientId)
{
physics.StopAllCoroutines();
physics.StartCoroutine(physics.CoExitVent(ventId));
return false;
}
if (clientId < 0) return false;
sender.AutoStartRpc(physics.NetId, RpcCalls.ExitVent, clientId);
sender.WritePacked(ventId);
sender.EndRpc();
return true;
}
}
}
+2
View File
@@ -258,6 +258,8 @@ public class CustomLogger
public static void ClearLog(bool check = true)
{
if (!Directory.Exists(Path.GetDirectoryName(LOGFilePath))) return;
if (!check || (File.Exists(LOGFilePath) && new FileInfo(LOGFilePath).Length > 0))
{
PrivateInstance?.Finish();
+58 -8
View File
@@ -25,6 +25,7 @@ internal static class ExtendedPlayerControl
public static readonly HashSet<byte> CancelBlackScreenFix = [];
private static readonly List<Vent> ResultBuffer = [];
public static readonly HashSet<byte> TempExiled = [];
public static readonly Dictionary<byte, string> NameWithRoleCache = [];
extension(PlayerControl player)
{
@@ -570,6 +571,8 @@ internal static class ExtendedPlayerControl
var players = Main.CachedAllPlayerControls();
HashSet<(PlayerControl target, RoleTypes roleType, int seerClientId)> setRoleCallsMap = [];
switch (oldRoleIsDesync, newRoleIsDesync)
{
// Desync role to normal role
@@ -591,7 +594,7 @@ internal static class ExtendedPlayerControl
// Set role type for seer
StartGameHostPatch.RpcSetRoleReplacer.RoleMap[(seer.PlayerId, player.PlayerId)] = (rememberRoleType, newCustomRole);
player.RpcSetRoleDesync(rememberRoleType, seerClientId);
setRoleCallsMap.Add((player, rememberRoleType, seerClientId));
if (self) continue;
@@ -609,13 +612,13 @@ internal static class ExtendedPlayerControl
if (!playerIsKiller && seer.Is(Team.Impostor)) rememberRoleType = RoleTypes.ImpostorGhost;
StartGameHostPatch.RpcSetRoleReplacer.RoleMap[(player.PlayerId, seer.PlayerId)] = (seerCustomRole.IsDesyncRole() ? RoleTypes.Crewmate : seerRoleType, seerCustomRole);
seer.RpcSetRoleDesync(rememberRoleType, player.OwnerId);
setRoleCallsMap.Add((seer, rememberRoleType, player.OwnerId));
continue;
}
// Set role type for player
StartGameHostPatch.RpcSetRoleReplacer.RoleMap[(player.PlayerId, seer.PlayerId)] = (rememberRoleType, seerCustomRole);
seer.RpcSetRoleDesync(rememberRoleType, player.OwnerId);
setRoleCallsMap.Add((seer, rememberRoleType, player.OwnerId));
}
break;
@@ -643,7 +646,7 @@ internal static class ExtendedPlayerControl
rememberRoleType = newRoleVN is CustomRoles.Noisemaker ? RoleTypes.Noisemaker : RoleTypes.Crewmate;
StartGameHostPatch.RpcSetRoleReplacer.RoleMap[(seer.PlayerId, player.PlayerId)] = (rememberRoleType, newCustomRole);
player.RpcSetRoleDesync(rememberRoleType, seerClientId);
setRoleCallsMap.Add((player, rememberRoleType, seerClientId));
if (self) continue;
@@ -656,13 +659,13 @@ internal static class ExtendedPlayerControl
rememberRoleType = RoleTypes.CrewmateGhost;
StartGameHostPatch.RpcSetRoleReplacer.RoleMap[(player.PlayerId, seer.PlayerId)] = (seerCustomRole.GetVNRole() is CustomRoles.Noisemaker ? RoleTypes.Noisemaker : RoleTypes.Crewmate, seerCustomRole);
seer.RpcSetRoleDesync(rememberRoleType, player.OwnerId);
setRoleCallsMap.Add((seer, rememberRoleType, player.OwnerId));
continue;
}
// Set role type for player
StartGameHostPatch.RpcSetRoleReplacer.RoleMap[(player.PlayerId, seer.PlayerId)] = (rememberRoleType, seerCustomRole);
seer.RpcSetRoleDesync(rememberRoleType, player.OwnerId);
setRoleCallsMap.Add((seer, rememberRoleType, player.OwnerId));
}
break;
@@ -685,12 +688,54 @@ internal static class ExtendedPlayerControl
rememberRoleType = newRoleType;
StartGameHostPatch.RpcSetRoleReplacer.RoleMap[(seer.PlayerId, player.PlayerId)] = (rememberRoleType, newCustomRole);
player.RpcSetRoleDesync(rememberRoleType, seerClientId);
setRoleCallsMap.Add((player, rememberRoleType, seerClientId));
}
break;
}
}
foreach (var targetGroup in setRoleCallsMap.GroupBy(x => x.target))
{
Dictionary<RoleTypes, int> counts = [];
RoleTypes globalRole = default;
int maxCount = 0;
foreach (var call in targetGroup)
{
int count = counts.TryGetValue(call.roleType, out int c) ? ++c : 1;
counts[call.roleType] = count;
if (count > maxCount)
{
maxCount = count;
globalRole = call.roleType;
}
}
int total = targetGroup.Count();
if (maxCount > 1 && 1 + total - maxCount < total)
{
targetGroup.Key.RpcSetRoleGlobal(globalRole);
LateTask.New(() =>
{
foreach (var call in targetGroup)
{
if (call.roleType != globalRole)
targetGroup.Key.RpcSetRoleDesync(call.roleType, call.seerClientId);
}
}, 0.2f);
}
else
{
foreach (var call in targetGroup)
targetGroup.Key.RpcSetRoleDesync(call.roleType, call.seerClientId);
}
}
if (loggerRoleMap)
{
@@ -1090,8 +1135,9 @@ internal static class ExtendedPlayerControl
{
try
{
if (NameWithRoleCache.TryGetValue(player?.PlayerId ?? 250, out string cache)) return cache;
bool addRoleName = GameStates.IsInGame && Options.CurrentGameMode is not CustomGameMode.FFA and not CustomGameMode.StopAndGo and not CustomGameMode.HotPotato and not CustomGameMode.Speedrun and not CustomGameMode.CaptureTheFlag and not CustomGameMode.NaturalDisasters and not CustomGameMode.RoomRush and not CustomGameMode.Quiz and not CustomGameMode.TheMindGame and not CustomGameMode.BedWars and not CustomGameMode.Deathrace and not CustomGameMode.Mingle and not CustomGameMode.Snowdown;
return $"{player?.Data?.PlayerName}" + (addRoleName ? $" ({player?.GetAllRoleName(forUser).RemoveHtmlTags().Replace('\n', ' ')})" : string.Empty);
return NameWithRoleCache[player?.PlayerId ?? 250] = $"{player?.Data?.PlayerName}" + (addRoleName ? $" ({player?.GetAllRoleName(forUser).RemoveHtmlTags().Replace('\n', ' ')})" : string.Empty);
}
catch (Exception e)
{
@@ -1375,6 +1421,7 @@ internal static class ExtendedPlayerControl
CustomRoles.Venter => true,
CustomRoles.Agent => true,
CustomRoles.Taskinator => false,
CustomRoles.Disguiser => true,
_ => Main.PlayerStates.TryGetValue(player.PlayerId, out PlayerState state) && state.Role.CanUseKillButton(player)
};
@@ -1791,6 +1838,9 @@ internal static class ExtendedPlayerControl
_ => Main.AllPlayerKillCooldown[player.PlayerId]
};
if (Options.CurrentGameMode == CustomGameMode.HideAndSeek)
Main.AllPlayerKillCooldown[player.PlayerId] = Seeker.KillCooldown.GetFloat();
if (player.PlayerId == LastImpostor.CurrentId) LastImpostor.SetKillCooldown();
if (player.Is(CustomRoles.Mare))
@@ -376,55 +376,6 @@ public static class CollectionExtensions
}
}
/// <summary>
/// Takes the specified number of random elements from the collection.
/// </summary>
/// <param name="count">The number of random elements to pick.</param>
/// <returns>A new collection with the specified number of random elements from the original collection.</returns>
public IEnumerable<T> TakeRandom(int count)
{
if (collection == null || collection.Count == 0 || count <= 0)
yield break;
int n = collection.Count;
// If asking for >= all elements, just return everything
if (count >= n)
{
for (int i = 0; i < n; i++)
yield return collection[i];
yield break;
}
// If k is small relative to n → pick unique indices via HashSet
// If k is large → invert selection (pick excluded indices instead)
if (count <= n / 2)
{
var chosen = new HashSet<int>();
while (chosen.Count < count)
{
int idx = IRandom.Instance.Next(n);
if (chosen.Add(idx))
yield return collection[idx];
}
}
else
{
// More efficient to exclude (n - count) items
int excludeCount = n - count;
var excluded = new HashSet<int>();
while (excluded.Count < excludeCount)
excluded.Add(IRandom.Instance.Next(n));
for (int i = 0; i < n; i++)
{
if (!excluded.Contains(i))
yield return collection[i];
}
}
}
/// <summary>
/// Returns a random element from a collection
/// </summary>
+7 -4
View File
@@ -145,6 +145,8 @@ public class PlayerState(byte playerId)
MainRole = role;
Role.Add(PlayerId);
ExtendedPlayerControl.NameWithRoleCache.Remove(PlayerId);
Logger.Info($"ID {PlayerId} ({Player.GetRealName()}) => {role}, CountTypes => {countTypes}", "SetMainRole");
@@ -158,10 +160,7 @@ public class PlayerState(byte playerId)
if (role.IsVanilla() || role.IsVanillaEHR())
Main.AbilityUseLimit.Remove(PlayerId);
}
if (Main.IntroDestroyed && GameStates.InGame)
{
if (PlayerId == PlayerControl.LocalPlayer.PlayerId && GameStates.IsInTask)
{
HudManager.Instance.SetHudActive(true);
@@ -239,6 +238,8 @@ public class PlayerState(byte playerId)
SetAddonCountTypes(role);
Logger.Info($" ID {PlayerId} ({Player?.GetRealName()}) => {role}, CountTypes => {countTypes}", "SetSubRole");
ExtendedPlayerControl.NameWithRoleCache.Remove(PlayerId);
}
private void SetAddonCountTypes(CustomRoles role)
@@ -361,6 +362,8 @@ public class PlayerState(byte playerId)
}
Utils.SendRPC(CustomRPC.RemoveSubRole, PlayerId, 1, (int)role);
ExtendedPlayerControl.NameWithRoleCache.Remove(PlayerId);
}
public void SetDead()
+1 -1
View File
@@ -1004,7 +1004,7 @@ public static class Options
var grouped = Main.CustomRoleValues.GroupBy(x =>
{
if (x is CustomRoles.GM or CustomRoles.NotAssigned or CustomRoles.LovingCrewmate or CustomRoles.LovingImpostor or CustomRoles.Convict or CustomRoles.Hider or CustomRoles.Seeker or CustomRoles.Fox or CustomRoles.Troll or CustomRoles.Jumper or CustomRoles.Detector or CustomRoles.Jet or CustomRoles.Dasher or CustomRoles.Locator or CustomRoles.Agent or CustomRoles.Venter or CustomRoles.Taskinator || x.IsForOtherGameMode() || x.IsVanilla() || x.IsVanillaEHR()) return 4;
if (x is CustomRoles.GM or CustomRoles.NotAssigned or CustomRoles.LovingCrewmate or CustomRoles.LovingImpostor or CustomRoles.Convict or CustomRoles.Hider or CustomRoles.Seeker or CustomRoles.Fox or CustomRoles.Troll or CustomRoles.Jumper or CustomRoles.Detector or CustomRoles.Jet or CustomRoles.Dasher or CustomRoles.Locator or CustomRoles.Agent or CustomRoles.Venter or CustomRoles.Taskinator or CustomRoles.Disguiser || x.IsForOtherGameMode() || x.IsVanilla() || x.IsVanillaEHR()) return 4;
if (x == CustomRoles.DoubleAgent) return 2;
if (x.IsAdditionRole()) return 3;
if (x.IsImpostor() || x.IsMadmate()) return 0;
+2 -1
View File
@@ -4283,7 +4283,8 @@ public static class Utils
if (!onMeeting) Main.DiedThisRound.Add(target.PlayerId);
// Record the first death
if (Main.FirstDied == string.Empty) Main.FirstDied = target.FriendCode;
if (Main.FirstDied == string.Empty && !disconnect)
Main.FirstDied = target.FriendCode;
switch (target.GetCustomRole())
{
+21 -3
View File
@@ -1109,7 +1109,8 @@ internal static class ChatCommands
public static void GameModePollCommand(PlayerControl player, string text, string[] args)
{
GMPollGameModes = Main.CustomGameModeValues[..^1].Where(x => Options.GMPollGameModesSettings[x].GetBool()).ToList();
string gmNames = string.Join(' ', GMPollGameModes.Select(x => GetString(x.ToString()).Replace(' ', '_')));
if (GMPollGameModes.Contains(CustomGameMode.HideAndSeek)) GMPollGameModes.Add((CustomGameMode)100);
string gmNames = string.Join(' ', GMPollGameModes.Select(x => GetString((int)x == 100 ? "HNS.ShiftAndSeek" : x.ToString()).Replace(' ', '_')));
var msg = $"/poll {GetString("GameModePoll.Question").TrimEnd('?')}? {gmNames}";
PollCommand(player, msg, msg.Split(' '));
}
@@ -1892,7 +1893,7 @@ internal static class ChatCommands
for (var i = 0; i < Math.Max(answers.Length, 2); i++)
{
var choiceLetter = (char)(i + 65);
msg += Utils.ColorString(gmPoll ? gmPollColors[i] : RandomColor(), $"{char.ToUpper(choiceLetter)}) {answers[i]}\n");
msg += Utils.ColorString(gmPoll && gmPollColors.Length > i ? gmPollColors[i] : RandomColor(), $"{char.ToUpper(choiceLetter)}) {answers[i]}\n");
PollVotes[choiceLetter] = 0;
PollAnswers[choiceLetter] = $"〖 {answers[i]} 〗";
}
@@ -1951,7 +1952,24 @@ internal static class ChatCommands
if (winners.Length is > 0 and < 4 && GameStates.IsLobby)
{
int winnerIndex = (winners.Length == 1 ? winners[0].Key : winners.RandomElement().Key) - 65;
if (gmPoll) Options.GameMode.SetValue((int)GMPollGameModes[winnerIndex] - 1, doSave: true, doSync: true);
if (gmPoll)
{
CustomGameMode winnerGM = GMPollGameModes[winnerIndex];
if ((int)winnerGM == 100)
{
winnerGM = CustomGameMode.HideAndSeek;
CustomHnS.SNS = true;
}
else if (winnerGM == CustomGameMode.HideAndSeek)
{
CustomHnS.SNS = false;
}
Options.GameMode.SetValue((int)winnerGM - 1, doSave: true, doSync: true);
}
if (mPoll) Main.NormalOptions.MapId = (byte)winnerIndex;
if (pPoll) Options.Preset?.SetValue(winnerIndex);
}
+2 -3
View File
@@ -276,7 +276,7 @@ public static class ChatManager
var writer = CustomRpcSender.Create("SendPreviousMessagesToAll", SendOption.Reliable);
var hasValue = false;
if (filtered.Length < 20) ClearChat(aapc);
if (filtered.Length < 20) ClearChat();
foreach (string str in filtered)
{
@@ -320,7 +320,7 @@ public static class ChatManager
if (!AmongUsClient.Instance.AmHost) return;
PlayerControl player = Main.AllAlivePlayerControlsCount == 0 ? PlayerControl.LocalPlayer : Main.CachedAlivePlayerControls().MinBy(x => x.PlayerId);
if (!player) return;
if (targets.Count == 0 || targets.Count >= Main.AllAlivePlayerControlsCount) SendEmptyMessage(null);
if (targets == null || targets.Count == 0 || targets.Count >= Main.AllAlivePlayerControlsCount) SendEmptyMessage(null);
else targets.Do(SendEmptyMessage);
return;
@@ -332,7 +332,6 @@ public static class ChatManager
if (toLocalPlayer) return;
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(player.NetId, (byte)RpcCalls.SendChat, SendOption.Reliable, toEveryone ? -1 : receiver.OwnerId);
writer.Write("<size=32767>.");
writer.Write(true);
AmongUsClient.Instance.FinishRpcImmediately(writer);
}
}
+36 -29
View File
@@ -6,10 +6,21 @@ using Exception = System.Exception;
namespace EHR;
// Thanks: https://github.com/AU-Avengers/TOU-Mira/blob/main/TownOfUs/Patches/AprilFools/DleksMapOptionPickerPatches.cs
[HarmonyPatch(typeof(GameStartManager))]
internal static class AllMapIconsPatch
{
private static void EnsureMapIcon(GameStartManager instance, MapNames map, string spritePath, float pixelsPerUnit)
{
if (instance.AllMapIcons.TrueForAll((Predicate<MapIconByName>)(x => x.Name != map)))
{
instance.AllMapIcons.Insert((int)map, new MapIconByName
{
Name = map,
MapIcon = Utils.LoadSprite(spritePath, pixelsPerUnit)
});
}
}
[HarmonyPatch(typeof(GameStartManager), nameof(GameStartManager.Start))]
[HarmonyPriority(Priority.First)]
[HarmonyPrefix]
@@ -17,28 +28,14 @@ internal static class AllMapIconsPatch
{
try
{
if (__instance.AllMapIcons.TrueForAll((Predicate<MapIconByName>)(x => x.Name != MapNames.Dleks)))
{
__instance.AllMapIcons.Insert((int)MapNames.Dleks, new MapIconByName
{
Name = MapNames.Dleks,
MapIcon = Utils.LoadSprite("EHR.Resources.Images.DleksBanner-Wordart.png", 160f)
});
}
EnsureMapIcon(__instance, MapNames.Dleks, "EHR.Resources.Images.DleksBanner-Wordart.png", 160f);
if (SubmergedCompatibility.Loaded)
{
if (__instance.AllMapIcons.TrueForAll((Predicate<MapIconByName>)(x => x.Name != (MapNames)6)))
{
__instance.AllMapIcons.Insert((int)(MapNames)6, new MapIconByName
{
Name = (MapNames)6,
MapIcon = Utils.LoadSprite("EHR.Resources.Images.Submerged-Wordart.png", 380f)
});
}
}
EnsureMapIcon(__instance, (MapNames)6, "EHR.Resources.Images.Submerged-Wordart.png", 380f);
}
catch { }
}
[HarmonyPatch(nameof(GameStartManager.Start))]
[HarmonyPostfix]
public static void Postfix_AllMapIcons(GameStartManager __instance)
@@ -49,26 +46,33 @@ internal static class AllMapIconsPatch
LateTask.New(() =>
{
if (Main.NormalOptions.MapId == 3)
{
Main.NormalOptions.MapId = 0;
if (Main.NormalOptions.MapId != 3) return;
Main.NormalOptions.MapId = 0;
if (__instance && __instance.MapImage)
__instance.UpdateMapImage(MapNames.Skeld);
if (!Options.RandomMapsMode.GetBool()) GameOptionsMapPickerPatch.SetDleks = true;
}
// Only force Dleks if random maps mode isn't active
if (!Options.RandomMapsMode.GetBool())
GameOptionsMapPickerPatch.SetDleks = true;
}, AmongUsClient.Instance.AmHost ? 1f : 4f, "Set Skeld Icon For Dleks Map");
}
catch (Exception e) { Utils.ThrowException(e); }
}
[HarmonyPatch(typeof(GameStartManager), nameof(GameStartManager.UpdateMapImage))]
[HarmonyPrefix]
public static bool Prefix_UpdateMapImage(GameStartManager __instance)
{
if (!__instance || !__instance.MapImage) return false;
if (GameOptionsMapPickerPatch.SetDleks)
{
__instance.MapImage.sprite = Utils.LoadSprite("EHR.Resources.Images.DleksBanner-Wordart.png", 160f);
return false;
}
return true;
}
}
@@ -89,6 +93,8 @@ public static class AutoselectDleksPatch
[HarmonyPatch]
public static class CreateGameOptionsPatch
{
private const string DleksSpritePath = "EHR.Resources.Images.DleksBanner-Wordart.png";
[HarmonyPatch(typeof(CreateGameOptions), nameof(CreateGameOptions.MapChanged))]
[HarmonyPrefix]
public static bool MapChangedPrefix(CreateGameOptions __instance)
@@ -97,22 +103,23 @@ public static class CreateGameOptionsPatch
{
__instance.mapBanner.flipX = false;
__instance.rendererBGCrewmates.sprite = __instance.bgCrewmates[0];
__instance.mapBanner.sprite = Utils.LoadSprite("EHR.Resources.Images.DleksBanner-Wordart.png", 100f);
__instance.mapBanner.sprite = Utils.LoadSprite(DleksSpritePath, 100f);
__instance.TurnOffCrewmates();
__instance.currentCrewSprites = __instance.skeldCrewSprites;
__instance.SetCrewmateGraphic(__instance.capacityOption.Value - 1f);
return false;
}
return !SubmergedCompatibility.Loaded || __instance.mapPicker.GetSelectedID() != 6;
}
[HarmonyPatch(typeof(CreateGameOptions), nameof(CreateGameOptions.Start))]
[HarmonyPrefix]
public static void SetupMapBackground(CreateGameOptions __instance)
{
if (__instance.currentCrewSprites == null)
{
__instance.mapBanner.sprite = Utils.LoadSprite("EHR.Resources.Images.DleksBanner-Wordart.png", 100f);
}
__instance.mapBanner.sprite = Utils.LoadSprite(DleksSpritePath, 100f);
__instance.currentCrewSprites ??= __instance.skeldCrewSprites;
__instance.mapTooltips[3] = StringNames.ToolTipSkeld;
}
@@ -133,4 +140,4 @@ public static class MapSelectionGameSettingPatch
__instance.Values = list.ToArray();
}
}
}
}
+1 -1
View File
@@ -179,7 +179,7 @@ internal static class ExileControllerWrapUpPatch
LateTask.New(() =>
{
if (ChatCommands.HasMessageDuringEjectionScreen)
ChatManager.ClearChat(Main.CachedAlivePlayerControls());
ChatManager.ClearChat();
}, 3f, log: false);
}
+1 -1
View File
@@ -930,7 +930,7 @@ internal static class BeginCrewmatePatch
}
case CustomGameMode.HideAndSeek:
{
__instance.TeamTitle.text = GetString("HideAndSeek");
__instance.TeamTitle.text = GetString(CustomHnS.SNS ? "HNS.ShiftAndSeek" : "HideAndSeek");
__instance.TeamTitle.color = __instance.BackgroundBar.material.color = new Color32(52, 94, 235, byte.MaxValue);
PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound(RoleTypes.Phantom);
__instance.ImpostorText.gameObject.SetActive(true);
+16 -34
View File
@@ -1537,7 +1537,7 @@ internal static class MeetingHudRpcClosePatch
{
public static bool AllowClose;
public static bool Prefix(MeetingHud __instance)
public static bool Prefix()
{
Logger.Info("MeetingHud.RpcClose is being called", "MeetingHudRpcClosePatch");
@@ -1552,41 +1552,23 @@ internal static class MeetingHudRpcClosePatch
if (Options.CurrentGameMode is CustomGameMode.Standard or CustomGameMode.TheMindGame)
{
if (AmongUsClient.Instance.AmClient)
__instance.Close();
NetworkedPlayerInfo info = CheckForEndVotingPatch.TempExiledPlayer;
MessageWriter writer = MessageWriter.Get(SendOption.Reliable);
writer.StartMessage(5);
writer.Write(AmongUsClient.Instance.GameId);
if (CheckForEndVotingPatch.TempExiledPlayer != null)
if (info && info.Object)
{
NetworkedPlayerInfo info = CheckForEndVotingPatch.TempExiledPlayer;
PlayerControl player = info.Object;
if (player != null)
{
writer.StartMessage(2);
writer.WritePacked(player.NetId);
writer.Write((byte)RpcCalls.SetName);
writer.Write(info.NetId);
writer.Write(CheckForEndVotingPatch.EjectionText);
writer.EndMessage();
}
MessageWriter writer = MessageWriter.Get(SendOption.Reliable);
writer.StartMessage(5);
writer.Write(AmongUsClient.Instance.GameId);
writer.StartMessage(2);
writer.WritePacked(info.Object.NetId);
writer.Write((byte)RpcCalls.SetName);
writer.Write(info.NetId);
writer.Write(CheckForEndVotingPatch.EjectionText);
writer.EndMessage();
writer.EndMessage();
AmongUsClient.Instance.SendOrDisconnect(writer);
writer.Recycle();
}
writer.StartMessage(2);
writer.WritePacked(__instance.NetId);
writer.Write((byte)RpcCalls.CloseMeeting);
writer.Write(CheckForEndVotingPatch.EjectionText);
writer.EndMessage();
writer.EndMessage();
AmongUsClient.Instance.SendOrDisconnect(writer);
writer.Recycle();
return false;
}
return true;
@@ -1596,7 +1578,7 @@ internal static class MeetingHudRpcClosePatch
[HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.HandleRpc))]
internal static class MeetingHudHandleRpcPatch
{
public static bool Prefix(MeetingHud __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader)
public static bool Prefix([HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader)
{
if (callId == (byte)RpcCalls.CloseMeeting)
{
+1
View File
@@ -200,6 +200,7 @@ internal static class ChangeRoleSettings
ExtendedPlayerControl.TempExiled.Clear();
Utils.CachedRoleSettings.Clear();
MeetingHudCastVotePatch.ShouldCancelVoteList.Clear();
ExtendedPlayerControl.NameWithRoleCache.Clear();
MeetingTimeManager.Init();
Main.DefaultCrewmateVision = Main.RealOptionsData.GetFloat(FloatOptionNames.CrewLightMod);
+35 -12
View File
@@ -1312,7 +1312,16 @@ internal static class ReportDeadBodyPatch
}); }
catch (Exception e) { ThrowException(e); }
try { if (Lovers.PrivateChat.GetBool() && Main.LoversPlayers.Count > 0) ChatManager.ClearChat(Main.EnumerateAlivePlayerControls().ExceptBy(Main.LoversPlayers.ConvertAll(x => x.PlayerId), x => x.PlayerId).ToArray()); }
try
{
if (Lovers.PrivateChat.GetBool() && Main.LoversPlayers.Count > 0)
{
if (GameStates.CurrentServerType != GameStates.ServerType.Vanilla)
ChatManager.ClearChat(Main.CachedAlivePlayerControls().FindAll(x => !Main.LoversPlayers.Exists(l => l.PlayerId == x.PlayerId)));
else
ChatManager.ClearChat();
}
}
catch (Exception e) { ThrowException(e); }
CustomSabotage.Reset();
@@ -1391,18 +1400,21 @@ internal static class ReportDeadBodyPatch
QuizMaster.Data.NumMeetings++;
}
if (Main.IsLoversDead && Lovers.LoverDieConsequence.GetValue() == 1 && Main.LoversPlayers.Exists(x => x && x.IsAlive()))
if (Main.IsLoversDead && Lovers.LoverDieConsequence.GetValue() == 1)
{
PlayerControl aliveLover = Main.LoversPlayers.First(x => x && x.IsAlive());
PlayerControl aliveLover = Main.LoversPlayers.Find(x => x && x.IsAlive());
switch (Lovers.LoverSuicideTime.GetValue())
if (aliveLover)
{
case 1:
aliveLover.Suicide(PlayerState.DeathReason.FollowingSuicide);
break;
case 2:
CheckForEndVotingPatch.TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.FollowingSuicide, aliveLover.PlayerId);
break;
switch (Lovers.LoverSuicideTime.GetValue())
{
case 1:
aliveLover.Suicide(PlayerState.DeathReason.FollowingSuicide);
break;
case 2:
CheckForEndVotingPatch.TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.FollowingSuicide, aliveLover.PlayerId);
break;
}
}
}
}
@@ -2065,8 +2077,19 @@ internal static class FixedUpdatePatch
if (!lowLoad)
{
Main.LoversPlayers.RemoveAll(x => !x);
if (!Main.HasJustStarted) Main.LoversPlayers.DoIf(x => !x.Is(CustomRoles.Lovers), x => x.RpcSetCustomRole(CustomRoles.Lovers));
for (int i = Main.LoversPlayers.Count - 1; i >= 0; i--)
{
PlayerControl lover = Main.LoversPlayers[i];
if (!lover)
{
Main.LoversPlayers.RemoveAt(i);
continue;
}
if (!Main.HasJustStarted && !lover.Is(CustomRoles.Lovers))
lover.RpcSetCustomRole(CustomRoles.Lovers);
}
}
if (Main.LoversPlayers.Exists(x => x.PlayerId == target.PlayerId) && (Main.LoversPlayers.Exists(x => x.PlayerId == lpId) || !seer.IsAlive()))
+5
View File
@@ -565,6 +565,11 @@ Click this badge to view our translation project:
>
> - Next button sprites (Inactive and Active)
> - Double task panel
### :star: [UnityDoorstop](https://github.com/Pietrodjaowjao/UnityDoorstop)
>
> - Modified doorstop_config.ini and winhttp.dll for packaging
### Endless Host Roles (EHR), with Endless Possibilities, brought to you by the Endless Network.
+1
View File
@@ -126,6 +126,7 @@ brownapex#1378 | 0926b55a8 | igoonalot | slurs in game |
frettedria#8062 | c29fae4c3 | | slurs in game |
pluralbug#5217 | cf91054b4 | | slurs in game |
oakaverage#9192 | 0aebc840d | Tevell67 | slurs in game |
signingwry#3704 | 800955a89 | | slurs in game |
## Griefers, Toxic, Harrasing, Racist
setmolar#4374 | | 藏族顶针 | Toxic |
+17
View File
@@ -4454,6 +4454,7 @@
"HNS.MaxNeutrals": "<#0000ff>Maximum</color> Number of <#ffab1b>Neutrals</color>",
"HNS.MinNeutrals": "<#00ffff>Minimum</color> Number of <#ffab1b>Neutrals</color>",
"HNS.PlayersSeeRoles": "Players See Each Other's Roles",
"HNS.ShiftAndSeek": "SHIFT AND SEEK",
"HNS.TaskCount": "Tasks:",
"HideAndSeek_MaxGameTime": "Maximum Game Length",
"TimeDecreaseOnCommonTaskComplete": "When Completing a Common Task, Reduce the Game Time by",
@@ -4461,6 +4462,7 @@
"TimeDecreaseOnOtherTaskComplete": "When Completing a Task That Doesn't Fit Any Category, Reduce the Game Time by",
"TimeDecreaseOnShortTaskComplete": "When Completing a Short Task, Reduce the Game Time by",
"TimeDecreaseOnSituationalTaskComplete": "When Completing a Situational Task, Reduce the Game Time by",
"HNSSeekers": "The <#ff1919>Seekers</color> are: {0}",
"SeekerCanVent": "Seeker Can Vent",
"SeekerSpeed": "Seeker Speed",
"SeekerVision": "Seeker Vision",
@@ -4492,6 +4494,7 @@
"FoxInfoLong": "Survive until the end to win",
"FoxSpeed": "Fox Speed",
"FoxVision": "Fox Vision",
"FoxHasVitals": "Fox has Vitals",
"Hider": "Hider",
"HiderInfo": "Complete tasks and survive until the end",
"HiderInfoLong": "Complete tasks and survive until the end",
@@ -4536,6 +4539,20 @@
"VenterInfoLong": "Use vents to catch Hiders",
"VenterSpeed": "Venter Speed",
"VenterVision": "Venter Vision",
"Disguiser": "Disguiser",
"DisguiserInfo": "Shapeshift!",
"DisguiserInfoLong": "Shapeshift!",
"DisguiserSpeed": "Disguiser Speed",
"DisguiserVision": "Disguiser Vision",
"DisguiserCanOnlyKillShapeshiftTarget": "Can Only Kill The Current Shapeshift Target",
"DisguiserPenaltyForWrongKillAttempt": "Penalty For Wrong Kill Attempts",
"DisguiserPFWKA.BlockKill": "Block Kill",
"DisguiserPFWKA.Suicide": "Suicide",
"DisguiserPFWKA.ResetKillCooldown": "Reset Kill Cooldown",
"DisguiserToleranceBeforeSuicide": "Tolerance (= number of wrong kill attempts allowed before suiciding)",
"DisguiserResetKillCooldownTo": "Reset Kill Cooldown To",
"DisguiserShapeshiftCooldown": "Disguiser Shapeshift Cooldown",
"DisguiserShapeshiftDuration": "Disguiser Shapeshift Duration",
"HotPotato": "HOT POTATO",
"ModeHotPotato": "Gamemode: Hot Potato",
"ModeDescribe.HotPotato": "In the Hot Potato gamemode, one player always has the hot potato, and they can pass it to anyone by going near someone. Each X seconds (X is set by the host), the player who holds the hot potato dies. The last player alive wins!\\n\\nNote: You cannot pass the hot potato to the player that just gave it to you (their name is colored in cyan, it means they cannot get the hot potato) unless there are only 2 players left.",
File diff suppressed because it is too large. Load diff
+8 -8
View File
@@ -1,5 +1,5 @@
{
"LanguageID": "10",
"LanguageID": "10 ",
"HostText": "EHR - Ospite",
"HostColor": "#00ffa5",
"HostIconInMeeting": "HOST: {0}",
@@ -331,7 +331,7 @@
"AlchemistGotShieldPotion": "<color=#ffffff><size=1.7><color=#e6d798>Nome della pozione: </color><color=#00ff97>Pozione dello Scudo</color>\\n<color=#e6d798>Descrizione: </color>Fornisce uno scudo temporaneo\\nAttiva tramite <color=#e6d798>Vent/Pet</color></size></color>",
"AlchemistGotSightPotion": "<color=#ffffff><size=1.7><color=#e6d798>Nome della pozione: </color><color=#eee5be>Pozione della Vista</color>\\n<color=#e6d798>Descrizione: </color>Aumenta la tua visione temporaneamente\\nAttiva tramite <color=#e6d798>Vent/Pet</color></size></color>",
"AlchemistGotSpeedPotion": "<color=#ffffff><size=1.7><color=#e6d798>Nome della pozione: </color><color=#ff8400>Pozione della Velocità</color>\\n<color=#e6d798>Descrizione: </color>Aumenta la tua velocità temporaneamente\\nAttiva tramite <color=#e6d798>Vent/Pet</color></size></color>",
"AlchemistGotSuicidePotion": "<color=#ffffff><size=1.7><color=#ffff00>Pozione goffa</color>\\nSembra che tu abbia mischiato gli ingredienti sbagliati!\\n<color=#ff1919>Bere questa pozione ti ucciderà!</color>\\nAttiva tramite <color=#e6d798>Vent/Pet</color></size></color>",
"AlchemistGotSuicidePotion": "<color=#ffffff><size=1.7><color=#ffff00>Pozione mortale</color>\\nSembra che tu abbia mischiato gli ingredienti sbagliati!\\n<color=#ff1919>Bere questa pozione ti ucciderà!</color>\\nAttiva tramite <color=#e6d798>Vent/Pet</color></size></color>",
"AlchemistGotTPPotion": "<color=#ffffff><size=1.7><color=#e6d798>Nome della pozione: </color><color=#42d1ff>Pozione del Teletrasporto</color>\\n<color=#e6d798>Descrizione: </color>Ti teletrasporta da un giocatore casuale\\nAttiva tramite <color=#e6d798>Vent/Pet</color></size></color>",
"AlchemistHasSpeed": "Pozione di velocità attiva",
"AlchemistHasVision": "Pozione di vista attiva",
@@ -625,7 +625,7 @@
"DoctorInfoLong": "(Astronauti): In qualità di Dottore, puoi visualizzare la causa della morte dei giocatori e accedere ai loro parametri vitali (vitals) finché la tua batteria è operativa.",
"DoctorTaskCompletedBatteryCharge": "Durata Batteria",
"DoctorVisibleToEveryone": "Tutti sanno chi è il <color=#80ffdd>Dottore</color>",
"DonutDelivery": "Consegna Ciambelle",
"DonutDelivery": "Ciambellaio",
"DonutDeliveryInfo": "Consegna ciambelle a tutti",
"DonutDeliveryInfoLong": "(Astronauti):\\nIn qualità di Ciambellaio, puoi consegnare ciambelle ai giocatori premendo il tasto uccidi su di loro. La ciambella non ha assolutamente alcun effetto, a parte il fatto che il bersaglio saprà di averne ricevuta una.",
"DonutDeliverCD": "Ricarica Consegna",
@@ -1573,9 +1573,9 @@
"VeteranSkillDuration": "Durata Allerta",
"VeteranSkillMaxOfUsage": "(Iniziale) Numero massimo di Allerte",
"VeteranVentButtonText": "Allerta",
"Vigilante": "Vigilante",
"Vigilante": "Incursore",
"VigilanteInfo": "Puoi uccidere 1 giocatore",
"VigilanteInfoLong": "(Astronauti): In qualità di Vigilante, puoi uccidere chiunque, ma solo una volta per partita. Dopo aver effettuato l'uccisione, potrai dedicarti a completare le tue task. In base alle impostazioni, potresti essere in grado di usare i condotti (vent).",
"VigilanteInfoLong": "(Astronauti): In qualità di Incursore, puoi uccidere chiunque, ma solo una volta per partita. Dopo aver effettuato l'uccisione, potrai dedicarti a completare le tue task. In base alle impostazioni, potresti essere in grado di usare i condotti (vent).",
"Whisperer": "Sussurratore",
"WhispererInfo": "Interroga le anime per ottenere informazioni",
"WhispererInfoLong": "(Astronauti):\\nIn qualità di Sussurratore, puoi chiedere informazioni alle anime dei giocatori defunti. Vedrai le anime dei giocatori morti (dopo la riunione successiva) e potrai interrogarle accarezzandole. Devi rimanere vicino all'anima per alcuni secondi. Otterrai quindi dettagli casuali sull'anima o sull'assassino, visualizzati sotto il tuo nome.",
@@ -1664,7 +1664,7 @@
"BardChance": "Possibilità <color=#ff1919>Bardo</color>",
"Blackmailer": "Influencer",
"BlackmailerInfo": "Influenza il voto dei giocatori",
"BlackmailerInfoLong": "(Impostori):\\nIn qualità di Influencer, puoi ricattare i giocatori cliccando una volta il tuo tasto uccidi su di loro. I voti dei giocatori ricattati saranno forzati a essere uguali al tuo voto. Clicca due volte per uccidere normalmente.",
"BlackmailerInfoLong": "(Impostori):\\nIn qualità di Influencer, puoi influenzare i giocatori cliccando una volta il tuo tasto uccidi su di loro. I voti dei giocatori influenzati saranno forzati a essere uguali al tuo voto. Clicca due volte per uccidere normalmente.",
"Blackmailer.AbilityExpires": "Abilità scaduta",
"Blackmailer.MaxBlackmailedPlayersAtOnce": "Massimo giocatori <#ffa500>influenzati</color> contemporaneamente",
"Blackmailer.MaxBlackmailedPlayersPerMeeting": "Massimo giocatori <#ffa500>influenzati</color> per riunione",
@@ -1766,9 +1766,9 @@
"CommanderUseAbilityNotify": "Il comandante vuole che tu usi la tua abilità",
"CommanderWhistleMode": "Fischia",
"CommanderWhistling": "Fischia",
"Consigliere": "Consigliere",
"Consigliere": "Veggente Malvagio",
"ConsigliereInfo": "Scopri i ruoli degli altri giocatori",
"ConsigliereInfoLong": "(Impostori): In qualità di Consigliere, puoi rivelare i ruoli degli altri giocatori usando il tuo tasto di uccisione.\n\nClick singolo: Rivela il ruolo\n\nDoppio click: Uccidi\n\nSe esaurisci gli utilizzi della rivelazione, il tuo tasto di uccisione tornerà a funzionare normalmente.",
"ConsigliereInfoLong": "(Impostori): In qualità di Veggente Malvagio, puoi rivelare i ruoli degli altri giocatori usando il tuo tasto di uccisione.\n\nClick singolo: Rivela il ruolo\n\nDoppio click: Uccidi\n\nSe esaurisci gli utilizzi della rivelazione, il tuo tasto di uccisione tornerà a funzionare normalmente.",
"Consort": "Limitatore",
"ConsortInfo": "Blocca ruolo e uccidi i giocatori",
"ConsortInfoLong": "(Impostori):\\nIn qualità di Limitatore, puoi bloccare il ruolo di un giocatore, impedendogli di uccidere, usare i condotti, sabotare e segnalare corpi per un certo periodo di tempo cliccando una volta il tasto uccidi su di lui. Fai doppio clic sul tasto uccidi per ucciderlo normalmente.\\n(La durata del blocco del ruolo è la stessa della durata dell'hacking del Glitch)",
+421 -421
View File
File diff suppressed because it is too large. Load diff
+9066 -9066
View File
File diff suppressed because it is too large. Load diff
+391 -391
View File
File diff suppressed because it is too large. Load diff
+9073 -9073
View File
File diff suppressed because it is too large. Load diff
+45 -45
View File
@@ -247,7 +247,7 @@
"NeverComboListTitle": "<u>职业和附加职业永远不能被一起分配:</u>",
"OracleCheckMsgTitle": "[ ★神谕揭示★ ]",
"PlayersNotReadyTitle": "<#ffff00><#ffab1b>{0}</color>个玩家还没准备!</color>他们是:",
"ReadyCheckTitle": "<#ff00>★就绪检查★</color>",
"ReadyCheckTitle": "<#ff00>★检查就绪★</color>",
"ShapeshiftGuesserUITitle.FirstLetterSelection": "选择该职业的开头字母",
"ShapeshiftGuesserUITitle.RoleSelection": "选择职业",
"ShapeshiftGuesserUITitle.TeamSelection": "选择该职业的阵营",
@@ -292,7 +292,7 @@
"AdventurerGun.Prediction": "预测",
"AdventurerGun.Proxy": "代理",
"AdventurerGun.RNG": "随机",
"AdventurerGun.Shield": "盾牌",
"AdventurerGun.Shield": "护盾",
"AdventurerGun.Wrench": "扳手",
"AdventurerIncreasedVisionDuration": "增加视野持续时间",
"AdventurerIngredientsDisplay": "{0}: {1}\\n跳管以选择制作该武器/抚摸宠物以查看下一个武器",
@@ -647,7 +647,7 @@
"DonutDelivered-15": "\\n甜甜圈是杀手锏,就像他们的不在场证明一样。",
"DonutDelivered-16": "\\n哎呀!甜甜圈交付失败。\\n他们可能更喜欢百吉饼...",
"DonutDelivered-17": "\\n拒绝!\\n他们正在节食减肥.",
"DonutDelivered-18": "\\n失败交付警报.\\n看来他们更喜欢冒名顶替的零食.",
"DonutDelivered-18": "\\n失败交付警报。\\n看来他们更喜欢内鬼的甜甜圈。",
"DonutDeliverSEAmount": "增加速度",
"DonutDeliverSEDelay": "速度提升延迟",
"DonutDeliverSEDuration": "速度提升持续时间",
@@ -1261,10 +1261,10 @@
"Retributionist.Success": "<#00ff00>✓</color> 正确!",
"Retributionist.SuccessOthers": "{0} 被一个 {1} 杀死了",
"Retributionist.TargetDead": "<#ffff00>你的目标死了!</color>\\n您可以使用<u>/retribute {id}</u>在下一次会议中杀死杀死目标的玩家。",
"Revenant": "Revenant",
"RevenantInfo": "Give the Crew Information you learnt from the Dead",
"RevenantInfoLong": "(Crewmates):\\nAs the Revenant, you are alive during the round and dead during meetings. Complete all your tasks in order to live through meetings and give the crew the information you learned from the dead. You cannot use guess commands. In addition, you can also chat with the dead in meetings.",
"Revenant.KnowInfo": "Revenant knows players'",
"Revenant": "复生者",
"RevenantInfo": "我自灵界归来,倾听亡魂之语",
"RevenantInfoLong": "(船员职业):\\n复生者在会议上是死的,其他地方是活的,完成所有任务后就就能复生向船员传递亡者的信息,你不能获得赌怪的附加职业,会议期间你可以和亡者聊天。",
"Revenant.KnowInfo": "复生者所知的玩家",
"Rhapsode": "歌唱家",
"RhapsodeInfo": "用你的天籁之音分散杀手的注意力!",
"RhapsodeInfoLong": "(船员职业):\\n歌唱家通过进入通风口/抚摸宠物开始歌唱。在歌唱的这段时间里,因为歌唱家唱的悦耳动听,全体玩家都无法变形或进入通风口。根据房主设置,船员可能不受影响。",
@@ -1419,7 +1419,7 @@
"SurvivorLastAbility": "剩余几人解锁最终能力",
"SurvivorCurrentAlive": "- 存活玩家数量:",
"SurvivorCantKillYet": "当前存活玩家数量大于解锁最终能力玩家数量,这意味着你还不能进行击杀。",
"SurvivorCantShieldYet": "The current number of players is greater than your shielding requirement, which means you cannot shield yet.",
"SurvivorCantShieldYet": "当前存活玩家数量大于套盾的请求,这意味着你还不能套盾。",
"Swapper": "正义的换票师",
"SwapperInfo": "逆转局势,颠倒乾坤",
"SwapperInfoLong": "(船员职业):\\n正义的换票师在会议时交换任意2人的票数,使用换票指令可以选择第一位玩家,再次使用换票指令可以选择第二位玩家,然后进行换票。\\n换票指令:「/sw [玩家编号]」。\\n换票师可以在玩家名字前看到该玩家的编号,或者使用/id指令查看所有玩家的编号。\\n\\n由于技术问题,原来的投票看起来没有改变,但这只是视觉上的,他们的投票仍然会被交换。",
@@ -1730,8 +1730,8 @@
"ChangelingInfo": "自行选择您喜爱的内鬼职业!",
"ChangelingInfoLong": "(内鬼职业):\\n幻形灵可以通过进入通风口或抚摸宠物来在可选的内鬼职业之间切换。幻形灵可以在自己的名字下方看到当前选择的职业。选择喜爱的职业,然后变形确认选择。幻形灵的职业将会变为选择的职业。",
"ChangelingCurrentRole": "您当前选中的职业: {0}",
"ChangelingChooseFail": "<#ff5555>X <#bb0000>Please enter a valid <color=#ff1919>Impostor</color> role.",
"ChangelingChosenRole": "<#00ff00>✓ <#00bb00>Your role will become {0} after the meeting.",
"ChangelingChooseFail": "<#ff5555>X <#bb0000>请输入一个有效的<color=#ff1919>内鬼</color>职业。",
"ChangelingChosenRole": "<#00ff00>✓ <#00bb00>会议结束后你将会变成{0}。",
"Chronomancer": "天文学家",
"ChronomancerInfo": "爆发吧!发狂吧!你的击杀冷却不受限制!",
"ChronomancerInfoLong": "(内鬼职业):\\n天文学家有一个电量条,当电量达到「100%」时,下一次击杀时天文学家就会进入屠杀模式,天文学家就可以展现杀戮光环,直到电量耗尽。其它情况下,天文学家的击杀冷却是正常的。",
@@ -1762,7 +1762,7 @@
"CommanderMarkMode": "标记目标",
"CommanderNotify": "将军希望您与他们会面",
"CommanderTarget": "<size=1.7>将军的目标</size>",
"CommanderUseAbilityMode": "命令使用技能",
"CommanderUseAbilityMode": "使用技能的命令",
"CommanderUseAbilityNotify": "将军命令你使用你的技能",
"CommanderWhistleMode": "口哨",
"CommanderWhistling": "口哨",
@@ -2498,7 +2498,7 @@
"Berserker.LowerKillCooldown": "更低的击杀冷却时间",
"Blockade": "阻碍者",
"BlockadeInfo": "设置障碍",
"BlockadeInfoLong": "(Neutrals):\\nAs the Blockade, you can vanish/pet/shapeshift to place blockades. No one other than you can go through them. All blockades disappear when a meeting starts.\\nKill everyone to win!",
"BlockadeInfoLong": "(中立职业):\\n阻碍者可以用隐身/宠物/变形来设置障碍,除了阻碍者无人能通过,会议召开后障碍重置。\\n杀死所有人取胜!",
"Blockade.BlockadeRadius": "障碍半径",
"BloodKnight": "嗜血骑士",
"BloodKnightInfo": "这一杯,敬给彼岸的你",
@@ -3751,7 +3751,7 @@
"HiddenInfoLong": "(附加职业):\\n隐藏者的尸体是匿名的。",
"Insane": "疯狂",
"InsaneInfo": "您疯狂了",
"InsaneInfoLong": "(附加组件):\\n疯狂玩家被造梦者编织。 当你的冷却时间结束时,你被迫在你触摸的任何玩家上使用你的能力。 如果造梦者死亡,您将丢失这个附加职业。",
"InsaneInfoLong": "(附加职业):\\n疯狂玩家被造梦者编织。 当你的冷却时间结束时,你被迫在你触摸的任何玩家上使用你的能力。 如果造梦者死亡,您将丢失这个附加职业。",
"Introvert": "内向者",
"IntrovertInfo": "你不喜欢附近有其他玩家",
"IntrovertInfoLong": "(附加职业):\\n内向者在其他玩家附近呆太长时间后会被传送到一个随机通风口。",
@@ -4527,7 +4527,7 @@
"HotPotato_HolderSpeed": "拿着烫手山芋的玩家的速度",
"HotPotato_HoldingNotify": "<#ffff00><size=2>你拿着烫手山芋!不传递给别人就得死</size></color>",
"HotPotato_Range": "传递范围",
"HotPotato_Time": "烫手山芋的持有者每次都会被杀死",
"HotPotato_Time": "烫手山芋爆炸时间",
"HotPotato_TimeLeftSuffix": "击杀于 ",
"KingOfTheZones": "山丘之王",
"ModeKingOfTheZones": "游戏模式:山丘之王",
@@ -4553,7 +4553,7 @@
"KOTZ.Notify.Tutorial.GameEnd.PointsOrTime": "<size=90%>The game ends if a team reaches <#ffff44>{0}</color> points or after <#ffff44>{1}m {2}s</color>.\\nWhen there's no tie, the team with the most points wins.</size>",
"KOTZ.Notify.Tutorial.GameEnd.TimeOnly": "<size=90%>After <#ffff44>{0} minutes and {1} seconds</color>, the team with the most points wins.\\n<size=70%>Upon a tie, the game ends when the tie breaks.</size></size>",
"KOTZ.Notify.Tutorial.Tagging": "<size=90%>Players can tag others using the kill button (cooldown: <#ffff44>{0}</color>s),\\nwhich teleports them outside the map for <#ffff44>{1}</color>s.</size>",
"KOTZ.Notify.Tutorial.ZonesMoving.AllAtOnce": "<size=90%>Every <#ffff44>{0}</color>s, all zones move to a different room.\\n(Indicated by timers next to the room names.)</size>",
"KOTZ.Notify.Tutorial.ZonesMoving.AllAtOnce": "<size=90%>每 <#ffff44>{0}</color>s, 所有区域会移动到不同房间。\\n(由房间名称旁边的计时器显示。)</size>",
"KOTZ.Notify.Tutorial.ZonesMoving.Downtime": "<size=90%>After a zone has moved, it stays neutral for <#ffff44>{0}</color>s,\\nmeaning no teams can have majority in it.\\n(Indicated by a gray timer.)</size>",
"KOTZ.Notify.Tutorial.ZonesMoving.Separately": "<size=90%>Every <#ffff44>{0}</color>s, a zone moves to a different room.\\n(Indicated by timers next to the room names.)</size>",
"KOTZ.PNTO.Less": "更少团队",
@@ -4566,7 +4566,7 @@
"KOTZ.SuffixHelp.Points": "<size=80%>分数: </size>",
"KOTZ.SuffixHelp.Zones.Plural": "<size=80%>区域: </size>",
"KOTZ.SuffixHelp.Zones.Single": "<size=80%>区域: </size>",
"KingOfTheZones.AllZonesMoveAtOnce": "All Zones Move At Once (if disabled, there will be an equal gap between zone movements)",
"KingOfTheZones.AllZonesMoveAtOnce": "所有区域立即移动(如果禁用,区域移动之间会有相等的间隔时间)",
"KingOfTheZones.AutoSetNumTeams": "根据玩家数量自动设置团队数量(如果以下设置不会产生团队)",
"KingOfTheZones.DowntimeAfterZoneMove": "Downtime After Zone Move (during downtime, the zone stays neutral)",
"KingOfTheZones.GameEndsByPoints": "如果一个团队获得了一定数量的分数,游戏结束",
@@ -4575,8 +4575,8 @@
"KingOfTheZones.NumTeams": "队伍数量",
"KingOfTheZones.NumZones": "区域数量",
"KingOfTheZones.PointsToWin": "获胜所需分数",
"KingOfTheZones.PreferNumTeams": "Prefer",
"KingOfTheZones.RespawnTime": "复活冷却时间",
"KingOfTheZones.PreferNumTeams": "偏好",
"KingOfTheZones.RespawnTime": "复活前等待时间",
"KingOfTheZones.SpawnProtectionTime": "复活保护时间",
"KingOfTheZones.TagCooldown": "击杀冷却时间",
"KingOfTheZones.ZoneMoveTime": "区域移动间隔",
@@ -8140,7 +8140,7 @@
"Snowdown.PowerUpPriceOption": "{powerup} 道具的价格(金币)",
"Snowdown.ShopHelp": "隐身:切換道具 | 宠物:购买指定的道具 | 破坏:退出商店",
"Snowdown.SnowballGainFrequencyOption": "初始雪球获取频率",
"Snowdown.SnowballSizeOption": "Snowball Size",
"Snowdown.SnowballSizeOption": "雪球大小",
"Snowdown.SnowballThrowSpeedOption": "丢雪球的速度",
"SnowdownButtonText": "丢",
"DoomTag": "循环追捕令",
@@ -8628,13 +8628,13 @@
"Indonesian": "印度尼西亚语",
"Persian": "波斯语",
"Polish": "波兰语",
"Arabic": "Arabic",
"Slovak": "Slovak",
"Romanian": "Romanian",
"Serbian": "Serbian",
"Vietnamese": "Vietnamese",
"Belarusian": "Belarusian",
"Turkish": "Turkish",
"Arabic": "阿拉伯语",
"Slovak": "斯洛伐克语",
"Romanian": "罗马尼亚语",
"Serbian": "塞尔维亚语",
"Vietnamese": "越南语",
"Belarusian": "白俄罗斯语",
"Turkish": "土耳其语",
"KickLowLevelPlayer": "踢出没有达到指定等级的玩家",
"KickBecauseLowLevel": "<b>{0}</b>因未达到房主规定的等级限制被踢",
"KickMobilePlayer": "踢出所有安卓端的玩家",
@@ -8680,7 +8680,7 @@
"Kick": "踢出",
"NoticeMe": "通知",
"NoticeEveryone": "通知所有人",
"EnableMovementChecking": "启用 EAC 检测无效的移动(针对速度黑客) (可能导致错误的正数)",
"EnableMovementChecking": "启用 EAC 检测无效的移动(针对移速挂)(可能导致错误的正数)",
"EnableEHRRateLimit": "启用 RPC 发送速率限制(防止外挂作弊让你崩游戏)",
"KickOnInvalidRPC": "踢出无效的 RPC 玩家(可能是由其他模组或外挂引起)",
"AutoDisplayKillLog": "结束后自动显示击杀记录",
@@ -8704,7 +8704,7 @@
"DIYGameSettings": "仅限自定义/n消息",
"PlayerCanSetColor": "玩家可使用/color指令",
"PlayerCanSetName": "玩家可使用/rename指令",
"PlayerCanTPInAndOut": "玩家可以使用 /tpin & /tpout 命令",
"PlayerCanTPInAndOut": "玩家可以使用 /tpin & /tpout 指令",
"FormatNameMode": "玩家名字同步模式",
"FormatNameModes.Color": "颜色",
"FormatNameModes.None": "禁用",
@@ -8714,7 +8714,7 @@
"ShowLongInfo": "显示职业的详细描述而不是简短说明",
"SendRoleDescriptionFirstMeeting": "首次会议自动向非模组玩家发送职业介绍",
"NoGameEnd": "游戏不结束",
"NoGameEndInfo": "'No Game End' is enabled. The game will not end automatically when it normally would. Only the host can end the game manually.",
"NoGameEndInfo": "\"游戏永不结束\"已启用。游戏永远不会自动结束,即使达成了胜利条件。只有房主可手动结束游戏。",
"AllowConsole": "启用终端",
"ShowAntiBlackoutWarning": "如果驱逐页面黑屏,显示反黑屏警告",
"PostLobbyCodeToEHRDiscordServer": "将房间代码发布到EHR网站上",
@@ -8789,7 +8789,7 @@
"AirshipChance": "<color=#ed0007>高空飞艇</color>地图随机到的概率",
"FungleChance": "<color=#ffa646>真菌世界</color>地图随机到的概率",
"OverrideSpeedForEachMap": "覆盖每张地图的速度",
"SpeedForMap": "玩家速度开启于{map}",
"SpeedForMap": "玩家在{map}里的速度",
"RandomSpawn": "随机出生点",
"AirshipAdditionalSpawn": "额外出生点(<color=#ed0007>高空飞艇</color>)",
"AirshipVariableElectrical": "电气室的门随机关闭(<color=#ed0007>高空飞艇</color>)",
@@ -8819,17 +8819,17 @@
"CommsCamouflage": "通信破坏时伪装",
"CommsCamouflageDisableOnFungle": "在<color=#ffa646>真菌世界</color>禁用",
"CommsCamouflageDisableOnMira": "在<color=#e84b56>米拉总部</color>禁用",
"CommsCamouflageLimit": "极限",
"CommsCamouflageLimit": "限制",
"CommsCamouflageLimitSetChance": "设置小黑人概率(每次通讯被破坏)",
"CommsCamouflageLimitChance": "可能有小黑人的概率",
"CommsCamouflageLimitSetFrequency": "设置小黑人频率(每次破坏的小黑人)",
"CommsCamouflageLimitSetFrequency": "设置小黑人频率(每X次通讯破坏产生小黑人效果)",
"CommsCamouflageLimitFrequency": "小黑人频率",
"CommsCamouflageLimitSetMaxTimes": "设置最大小黑人时间",
"CommsCamouflageLimitMaxTimesPerGame": "每次游戏的最大小黑人时间",
"CommsCamouflageLimitMaxTimesPerRound": "每轮最大小黑人时间",
"CommsCamouflageSetSameSpeed": "所有玩家在隐蔽期间速度相同",
"CommsCamouflagePreventRound1": "第一轮不要触发小黑人",
"DisableReportWhenCC": "当伪装激活时,禁用尸体报告",
"DisableReportWhenCC": "当小黑人激活时,禁用尸体报告",
"SabotageCooldownControl": "修改破坏冷却时长",
"SabotageCooldown": "破坏冷却时长",
"SabotageTimeControl": "修改破坏时间限制",
@@ -8853,7 +8853,7 @@
"EnableCustomSabotages": "允许自定义破坏",
"EnableGrabOxygenMaskCustomSabotage": "允许启用获取氧气面罩(通过通讯破坏发起,按按钮两次以完成)",
"MenuTitle.Disable": "★ 禁用相关设定",
"DisableShieldAnimations": "禁用不必要的盾牌动画",
"DisableShieldAnimations": "禁用不必要的破盾动画",
"DisableKillAnimationOnGuess": "禁用在会议时被猜死的击杀动画",
"DisableShapeshiftAnimations": "禁用变形时的动画",
"DisableAllShapeshiftAnimations": "禁用所有变形时的动画",
@@ -8872,7 +8872,7 @@
"DisableCloseDoor": "关闭门的破坏",
"DisableWhisperCommand": "禁用 /whisper 指令",
"DisableSpectateCommand": "禁用 /specater 指令",
"Disable8ballCommand": "禁用 /8ball 命令",
"Disable8ballCommand": "禁用 /8ball 指令",
"DisableVoteStartCommand": "禁用 /votestart 指令",
"DisableVentingOn1v1": "在1v1时禁用管道",
"DisableSabotagingOn1v1": "在1v1时禁用破坏",
@@ -8939,7 +8939,7 @@
"WhenSkipVoteIgnoreNoDeadBody": "忽略无尸体会议",
"WhenSkipVoteIgnoreEmergency": "忽略紧急会议按钮发起的会议",
"MenuTitle.GameCommands": "游戏命令",
"AnagramLanguage": "字谜语(Anagram Word Language)",
"AnagramLanguage": "字谜语言",
"AnagramLang.Auto": "自动(跟随系统)",
"AnagramLang.English": "英语",
"AnagramLang.Spanish": "西班牙语",
@@ -8976,13 +8976,13 @@
"GameTimeLimit": "游戏时间限制",
"GameTimerEnded": "游戏时间结束",
"GameTimeLimitRunsDuringMeetings": "会议期间的游戏时间限制",
"OverrideVisionInVents": "在风险中覆盖视野效果",
"OverrideVisionInVents": "在管道中覆盖视野",
"InVentVisionForTeam": "{team} 通风口中的视野",
"MenuTitle.Ghost": "★ 鬼魂设定★",
"GhostCanSeeOtherRoles": "鬼魂可看他人身份",
"GhostCanSeeOtherVotes": "鬼魂可以看到投票人的颜色",
"GhostCanSeeDeathReason": "鬼魂可知道其他玩家的死因",
"MenuTitle.AFKDetection": "★ AFK 检测 ★",
"MenuTitle.AFKDetection": "★ 挂机检测 ★",
"EnableAFKDetector": "启用挂机玩家检测器(也用于检测和修复黑屏)",
"AFKConsequence": "对挂机玩家造成影响",
"AFKConsequence.Nothing": "无",
@@ -9336,7 +9336,7 @@
"CommandArgs.JailTalk.Message": "发送给狱警/被监禁的玩家的消息",
"CommandArgs.Kill.Id": "要杀掉的玩家ID",
"CommandArgs.Level.Level": "你的新等级",
"CommandArgs.Mark.Id": "The player's ID to mark",
"CommandArgs.Mark.Id": "标记的玩家ID",
"CommandArgs.Medium.Answer": "是/否",
"CommandArgs.MessageWait.Duration": "消息发送需要等待的时间",
"CommandArgs.Mute.Id": "要禁言的人的玩家ID",
@@ -9444,7 +9444,7 @@
"CommandDescription.Level": "改变你的等级",
"CommandDescription.MTHY": "召开会议或结束当前会议",
"CommandDescription.MapPoll": "开始投票选择下一个游戏地图。",
"CommandDescription.Mark": "Mark a player as your target as Markseeker.",
"CommandDescription.Mark": "曝光者标记一个玩家。",
"CommandDescription.Medium": "回答通灵师的问题",
"CommandDescription.MessageWait": "为系统消息设置缓冲时间",
"CommandDescription.Mute": "禁言某人直到游戏开始恢复",
@@ -9462,7 +9462,7 @@
"CommandDescription.QS": "查看测验大师提出的问题",
"CommandDescription.R": "查看职业列表和具体职业介绍",
"CommandDescription.Ready": "将自己标记为已准备",
"CommandDescription.ReadyCheck": "临行前的准备(即确认谁在挂机)(30S后显示结果)",
"CommandDescription.ReadyCheck": "准备开始检测(即确认谁在挂机)(30s后显示结果)",
"CommandDescription.Rename": "给你一个新名",
"CommandDescription.Reroll": "重置者可以在重置你的职业,会议后生效。",
"CommandDescription.Retribute": "作为惩罚者猜测谁杀了你标记的玩家",
@@ -9788,7 +9788,7 @@
"EAC.CheatDetected.EAC": "检测到外挂使用 (AUM)",
"EAC.CheatDetected.HighLevel": "警告:EAC正在抵御炸房外挂",
"EAC.CheatDetected.LowLevel": "警告:EAC检测到可能有外挂玩家",
"EAC.ClientTimeout": "{0}|{1} didn't send their full data within 25s, most likely a hacker",
"EAC.ClientTimeout": "{0}|{1} 在25秒内未能够发送完整数据,极有可能是外挂。",
"ECMO.OriginalTeam": "原始阵营",
"EGCanGuessAdt": "可以猜测附加职业",
"EGCanGuessImp": "可以猜测<color=#ff1919>内鬼</color>",
@@ -9965,7 +9965,7 @@
"LoadingHint.5": "您有想法吗?\n将您的建议发布到我们的 Discord 服务器(主菜单上的链接)!\n我们会在将来的更新中考虑它!",
"LoadingHint.6": "你知道吗?\n你可以激活黑名单来永久禁止玩家使用代码加入!",
"LoadingHint.7": "您知道吗?\n您可以直接在游戏中使用/addmod 和 /deletemod 命令添加或取消协管!",
"LoadingHint.8": "您知道吗?\n黑客通常没有代码,所以您可以轻松地在设置中启用保护!",
"LoadingHint.8": "您知道吗?\n外挂通常没有好友代码,所以您可以轻松地在设置中启用防护!",
"LoadingHint.9": "您知道吗?\n您可以快速更改游戏设置,而无需使用 /changesette (/cs)打开菜单!\n示例:/cs map pols",
"LoadingHint.10": "您知道吗?\n您可以自定义大厅标签!",
"LoadingHint.11": "你知道吗?\n房主可以使用 /setrole 和 /setaddon 来设置下一场游戏的职业和附加职业!",
@@ -10112,7 +10112,7 @@
"NKCanFindMarshall": "展现者向<#ffab1b>带刀中立</color>展示",
"NKWinsBySabotageIfNoImpAlive": "<#ff1919>带刀<#ff1919>中立可以破坏获胜如果<#ff1919>内鬼</color>全部死亡",
"NNKCanFindMarshall": "展现者向<#ffff00>不带刀中立</color>展示",
"NameDisplayAddonsOnlyInMeetings": "仅在会议中在角色名称旁边显示附加组件(如果上述设置关闭)",
"NameDisplayAddonsOnlyInMeetings": "仅在会议中在角色名称旁边显示附加职业(如果上述设置关闭)",
"NegativeEffectDuration": "低视野/慢速度的持续时间",
"NeutralCanBeInLove": "<color=#7f8c8d>中立阵营</color>可以成为<color=#ff9ace>恋人</color>",
"NeutralCanBeRole": "<color=#ffab1b>中立阵营</color>可以成为{role}",
@@ -10201,7 +10201,7 @@
"RestEHRSetting": "已恢复EHR的默认设置",
"RevealMaxCount": "最大揭示次数",
"RitualMaxCount": "最大揭示次数",
"SettingsForRoleText": "设置给",
"SettingsForRoleText": "针对性设置",
"ShapeshiftCooldown": "<color=#ff1919>变形</color>冷却时间",
"ShapeshiftDuration": "<color=#ff1919>变形</color>持续时间",
"ShareLobbyMinPlayer": "当玩家数量达到时自动分享大厅代码",
+128
View File
@@ -0,0 +1,128 @@
using AmongUs.GameOptions;
namespace EHR.Roles;
public class Disguiser : RoleBase, IHideAndSeekRole
{
public static bool On;
public static OptionItem CanOnlyKillShapeshiftTarget;
public static OptionItem PenaltyForWrongKillAttempt;
public static OptionItem ToleranceBeforeSuicide;
public static OptionItem ResetKillCooldownTo;
public static OptionItem ShapeshiftCooldown;
public static OptionItem ShapeshiftDuration;
public static OptionItem Vision;
public static OptionItem Speed;
public override bool IsEnable => On;
public Team Team => Team.Impostor;
public int Chance => CustomRoles.Disguiser.GetMode();
public int Count => CustomRoles.Disguiser.GetCount();
public float RoleSpeed => Speed.GetFloat();
public float RoleVision => Vision.GetFloat();
public override void SetupCustomOption()
{
Options.SetupRoleOptions(69_211_1101, TabGroup.ImpostorRoles, CustomRoles.Disguiser, CustomGameMode.HideAndSeek);
Vision = new FloatOptionItem(69_211_1103, "DisguiserVision", new(0.05f, 5f, 0.05f), 0.25f, TabGroup.ImpostorRoles)
.SetGameMode(CustomGameMode.HideAndSeek)
.SetValueFormat(OptionFormat.Multiplier)
.SetColor(new(179, 70, 70, byte.MaxValue))
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Disguiser]);
Speed = new FloatOptionItem(69_213_1104, "DisguiserSpeed", new(0.05f, 5f, 0.05f), 1.5f, TabGroup.ImpostorRoles)
.SetGameMode(CustomGameMode.HideAndSeek)
.SetValueFormat(OptionFormat.Multiplier)
.SetColor(new(179, 70, 70, byte.MaxValue))
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Disguiser]);
CanOnlyKillShapeshiftTarget = new BooleanOptionItem(69_213_1105, "DisguiserCanOnlyKillShapeshiftTarget", true, TabGroup.ImpostorRoles)
.SetGameMode(CustomGameMode.HideAndSeek)
.SetColor(new(179, 70, 70, byte.MaxValue))
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Disguiser]);
PenaltyForWrongKillAttempt = new StringOptionItem(69_213_1106, "DisguiserPenaltyForWrongKillAttempt", ["DisguiserPFWKA.BlockKill", "DisguiserPFWKA.Suicide", "DisguiserPFWKA.ResetKillCooldown"], 1, TabGroup.ImpostorRoles)
.SetGameMode(CustomGameMode.HideAndSeek)
.SetColor(new(179, 70, 70, byte.MaxValue))
.SetParent(CanOnlyKillShapeshiftTarget)
.RegisterUpdateValueEvent((_, _, newValue) =>
{
ToleranceBeforeSuicide.SetHidden(newValue != 1);
ResetKillCooldownTo.SetHidden(newValue != 2);
})
.SetRunEventOnLoad(true);
ToleranceBeforeSuicide = new IntegerOptionItem(69_213_1107, "DisguiserToleranceBeforeSuicide", new(0, 14, 1), 2, TabGroup.ImpostorRoles)
.SetGameMode(CustomGameMode.HideAndSeek)
.SetValueFormat(OptionFormat.Times)
.SetColor(new(179, 70, 70, byte.MaxValue))
.SetParent(PenaltyForWrongKillAttempt);
ResetKillCooldownTo = new FloatOptionItem(69_213_1108, "DisguiserResetKillCooldownTo", new(0.5f, 120f, 0.5f), 10f, TabGroup.ImpostorRoles)
.SetGameMode(CustomGameMode.HideAndSeek)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(new(179, 70, 70, byte.MaxValue))
.SetParent(PenaltyForWrongKillAttempt);
ShapeshiftCooldown = new IntegerOptionItem(69_213_1109, "DisguiserShapeshiftCooldown", new(0, 180, 1), 0, TabGroup.ImpostorRoles)
.SetGameMode(CustomGameMode.HideAndSeek)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(new(179, 70, 70, byte.MaxValue))
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Disguiser]);
ShapeshiftDuration = new IntegerOptionItem(69_213_1110, "DisguiserShapeshiftDuration", new(0, 180, 1), 30, TabGroup.ImpostorRoles)
.SetGameMode(CustomGameMode.HideAndSeek)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(new(179, 70, 70, byte.MaxValue))
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Disguiser]);
}
public override void Add(byte playerId)
{
On = true;
if (CanOnlyKillShapeshiftTarget.GetBool() && PenaltyForWrongKillAttempt.GetValue() == 1)
playerId.SetAbilityUseLimit(ToleranceBeforeSuicide.GetInt());
}
public override void Init()
{
On = false;
}
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
AURoleOptions.ShapeshifterCooldown = ShapeshiftCooldown.GetInt();
AURoleOptions.ShapeshifterDuration = ShapeshiftDuration.GetInt();
}
public static bool CheckMurder(PlayerControl killer, PlayerControl target)
{
if (CanOnlyKillShapeshiftTarget.GetBool() && killer.shapeshiftTargetPlayerId != target.PlayerId)
{
switch (PenaltyForWrongKillAttempt.GetValue())
{
case 1:
{
if (killer.GetAbilityUseLimit() < 1)
killer.Suicide();
else
killer.RpcRemoveAbilityUse();
break;
}
case 2:
{
killer.SetKillCooldown(ResetKillCooldownTo.GetFloat());
break;
}
}
return false;
}
return true;
}
}
+7 -1
View File
@@ -6,6 +6,7 @@ internal class Fox : RoleBase, IHideAndSeekRole
public static OptionItem Vision;
public static OptionItem Speed;
public static OptionItem HasVitals;
public override bool IsEnable => On;
public Team Team => Team.Neutral;
@@ -21,7 +22,7 @@ internal class Fox : RoleBase, IHideAndSeekRole
.SetGameMode(CustomGameMode.HideAndSeek);
Options.SetupRoleOptions(69_211_301, TabGroup.NeutralRoles, CustomRoles.Fox, CustomGameMode.HideAndSeek);
Vision = new FloatOptionItem(69_211_303, "FoxVision", new(0.05f, 5f, 0.05f), 1.25f, TabGroup.NeutralRoles)
.SetGameMode(CustomGameMode.HideAndSeek)
.SetValueFormat(OptionFormat.Multiplier)
@@ -33,6 +34,11 @@ internal class Fox : RoleBase, IHideAndSeekRole
.SetValueFormat(OptionFormat.Multiplier)
.SetColor(new(0, 255, 0, byte.MaxValue))
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fox]);
HasVitals = new BooleanOptionItem(69_213_305, "FoxHasVitals", true, TabGroup.NeutralRoles)
.SetGameMode(CustomGameMode.HideAndSeek)
.SetColor(new(0, 255, 0, byte.MaxValue))
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fox]);
}
public override void Add(byte playerId)
+4 -1
View File
@@ -254,7 +254,10 @@ public class Alchemist : RoleBase
{
InvisTimer = null;
if (!pc || !pc.IsAlive()) return;
Main.EnumeratePlayerControls().Without(pc).Do(x => instance.RpcExitVentDesync(ventId, x));
bool hasValue = false;
CustomRpcSender sender = CustomRpcSender.Create("Alchemist RpcExitVentDesync calls", SendOption.Reliable).StartPackedMessage();
Main.EnumeratePlayerControls().Without(pc).Do(x => hasValue |= sender.RpcExitVentDesync(instance, ventId, x));
sender.SendMessage(dispose: !hasValue);
pc.Notify(GetString("SwooperInvisStateOut"));
}, onTick: pc.IsModdedClient() ? null : () => pc.Notify(string.Format(GetString("SwooperInvisStateCountdown"), (int)Math.Ceiling(InvisTimer.Remaining.TotalSeconds)), overrideAll: true), onCanceled: () => InvisTimer = null);
@@ -153,7 +153,7 @@ public class Swooper : RoleBase
if (!AmongUsClient.Instance.AmHost) return;
var player = SwooperId.GetPlayer();
if (player == null || !player.IsAlive()) return;
if (!player || !player.IsAlive()) return;
if (!player.IsModdedClient() && !(UsedRole != CustomRoles.Chameleon && UsePhantomBasis.GetBool() && (UsedRole != CustomRoles.Wraith || UsePhantomBasisForNKs.GetBool())))
player.Notify(GetString("SwooperCanVent"), 10f);
@@ -162,7 +162,7 @@ public class Swooper : RoleBase
if (!AmongUsClient.Instance.AmHost) return;
var player = SwooperId.GetPlayer();
if (player == null || !player.IsAlive()) return;
if (!player || !player.IsAlive()) return;
if (!(UsePhantomBasis.GetBool() && (UsedRole != CustomRoles.Wraith || UsePhantomBasisForNKs.GetBool())))
player.Notify(string.Format(GetString("CDPT"), (int)Math.Ceiling(CooldownTimer.Remaining.TotalSeconds)), 3f, true);
@@ -178,7 +178,12 @@ public class Swooper : RoleBase
InvisTimer = null;
if (UsedRole == CustomRoles.Chameleon && !UsePets.GetBool())
Main.EnumeratePlayerControls().Without(player).Do(x => player.MyPhysics.RpcExitVentDesync(ventId, x));
{
bool hasValue = false;
CustomRpcSender sender = CustomRpcSender.Create("Swooper RpcExitVentDesync calls", SendOption.Reliable).StartPackedMessage();
Main.EnumeratePlayerControls().Without(player).Do(x => hasValue |= sender.RpcExitVentDesync(player.MyPhysics, ventId, x));
sender.SendMessage(dispose: !hasValue);
}
else
player.RpcMakeVisible(phantom: UsedRole == CustomRoles.Swooper);
@@ -268,7 +273,7 @@ public class Swooper : RoleBase
public override string GetSuffix(PlayerControl seer, PlayerControl target, bool hud = false, bool meeting = false)
{
if (!hud || seer == null || seer.PlayerId != SwooperId || !GameStates.IsInTask || ExileController.Instance || !seer.IsAlive()) return string.Empty;
if (!hud || seer.PlayerId != SwooperId || meeting || !seer.IsAlive()) return string.Empty;
Suffix.Clear();
+1
View File
@@ -0,0 +1 @@
4.5.1
@@ -1,194 +1,194 @@
[Caching]
## Enable/disable assembly metadata cache
## Enabling this will speed up discovery of plugins and patchers by caching the metadata of all types BepInEx discovers.
# Setting type: Boolean
# Default value: true
EnableAssemblyCache = true
[Detours]
## The native provider to use for managed detours
# Setting type: DetourProvider
# Default value: Default
# Acceptable values: Default, Dobby, Funchook
DetourProviderType = Default
[Harmony.Logger]
## Specifies which Harmony log channels to listen to.
## NOTE: IL channel dumps the whole patch methods, use only when needed!
# Setting type: LogChannel
# Default value: Warn, Error
# Acceptable values: None, Info, IL, Warn, Error, Debug, All
# Multiple values can be set at the same time by separating them with , (e.g. Debug, Warning)
LogChannels = Warn, Error
[IL2CPP]
## Whether to run Il2CppInterop automatically to generate Il2Cpp support assemblies when they are outdated.
## If disabled assemblies in `BepInEx/interop` won't be updated between game or BepInEx updates!
##
# Setting type: Boolean
# Default value: true
UpdateInteropAssemblies = true
## URL to the ZIP of managed Unity base libraries.
## The base libraries are used by Il2CppInterop to generate interop assemblies.
## The URL can include {VERSION} template which will be replaced with the game's Unity engine version.
##
# Setting type: String
# Default value: https://unity.bepinex.dev/libraries/{VERSION}.zip
UnityBaseLibrariesSource = https://unity.bepinex.dev/libraries/{VERSION}.zip
## The RegEx string to pass to Il2CppAssemblyUnhollower for renaming obfuscated names.
## All types and members matching this RegEx will get a name based on their signature,
## resulting in names that persist after game updates.
##
# Setting type: String
# Default value:
UnhollowerDeobfuscationRegex =
## If enabled, Il2CppInterop will use xref to find dead methods and generate CallerCount attributes.
# Setting type: Boolean
# Default value: true
ScanMethodRefs = false
## If enabled, BepInEx will save dummy assemblies generated by an Cpp2IL dumper into BepInEx/dummy.
# Setting type: Boolean
# Default value: false
DumpDummyAssemblies = false
## The path to the folder where IL2CPPInterop assemblies are stored.
## Supports the following placeholders:
## {BepInEx} - Path to the BepInEx folder.
## {ProcessName} - Name of the current process
##
# Setting type: String
# Default value: {BepInEx}
IL2CPPInteropAssembliesPath = {BepInEx}
## Automatically load all interop assemblies right before loading plugins.
## Some plugins may not work properly without this, but it may cause issues in some games.
##
# Setting type: Boolean
# Default value: true
PreloadIL2CPPInteropAssemblies = true
## The path to the IL2CPP metadata file.
## Supports the following placeholders:
## {BepInEx} - Path to the BepInEx folder.
## {ProcessName} - Name of the current process
## {GameDataPath} - Path to the game's Data folder.
##
# Setting type: String
# Default value: {GameDataPath}/il2cpp_data/Metadata/global-metadata.dat
GlobalMetadataPath = {GameDataPath}/il2cpp_data/Metadata/global-metadata.dat
[Logging]
## Enables showing unity log messages in the BepInEx logging system.
# Setting type: Boolean
# Default value: true
UnityLogListening = true
[Logging.Console]
## Enables showing a console for log output.
# Setting type: Boolean
# Default value: true
Enabled = true
## If enabled, will prevent closing the console (either by deleting the close button or in other platform-specific way).
# Setting type: Boolean
# Default value: false
PreventClose = false
## If true, console is set to the Shift-JIS encoding, otherwise UTF-8 encoding.
# Setting type: Boolean
# Default value: false
ShiftJisEncoding = false
## Hints console manager on what handle to assign as StandardOut. Possible values:
## Auto - lets BepInEx decide how to redirect console output
## ConsoleOut - prefer redirecting to console output; if possible, closes original standard output
## StandardOut - prefer redirecting to standard output; if possible, closes console out
##
# Setting type: ConsoleOutRedirectType
# Default value: Auto
# Acceptable values: Auto, ConsoleOut, StandardOut
StandardOutType = Auto
## Which log levels to show in the console output.
# Setting type: LogLevel
# Default value: Fatal, Error, Warning, Message, Info
# Acceptable values: None, Fatal, Error, Warning, Message, Info, Debug, All
# Multiple values can be set at the same time by separating them with , (e.g. Debug, Warning)
LogLevels = Fatal, Error, Warning, Message, Info
[Logging.Disk]
## Appends to the log file instead of overwriting, on game startup.
# Setting type: Boolean
# Default value: false
AppendLog = false
## Enables writing log messages to disk.
# Setting type: Boolean
# Default value: true
Enabled = true
## Only displays the specified log levels in the disk log output.
# Setting type: LogLevel
# Default value: Fatal, Error, Warning, Message, Info
# Acceptable values: None, Fatal, Error, Warning, Message, Info, Debug, All
# Multiple values can be set at the same time by separating them with , (e.g. Debug, Warning)
LogLevels = Fatal, Error, Warning, Message, Info
## If true, instantly writes any received log entries to disk.
## This incurs a major performance hit if a lot of log messages are being written, however it is really useful for debugging crashes.
##
# Setting type: Boolean
# Default value: false
InstantFlushing = false
## The maximum amount of concurrent log files that will be written to disk.
## As one log file is used per open game instance, you may find it necessary to increase this limit when debugging multiple instances at the same time.
##
# Setting type: Int32
# Default value: 5
ConcurrentFileLimit = 5
## Include unity log messages in log file output.
# Setting type: Boolean
# Default value: false
WriteUnityLog = false
[Preloader]
## Specifies which MonoMod backend to use for Harmony patches. Auto uses the best available backend.
## This setting should only be used for development purposes (e.g. debugging in dnSpy). Other code might override this setting.
# Setting type: MonoModBackend
# Default value: auto
# Acceptable values: auto, dynamicmethod, methodbuilder, cecil
HarmonyBackend = auto
## If enabled, BepInEx will save patched assemblies into BepInEx/DumpedAssemblies.
## This can be used by developers to inspect and debug preloader patchers.
# Setting type: Boolean
# Default value: false
DumpAssemblies = false
## If enabled, BepInEx will load patched assemblies from BepInEx/DumpedAssemblies instead of memory.
## This can be used to be able to load patched assemblies into debuggers like dnSpy.
## If set to true, will override DumpAssemblies.
# Setting type: Boolean
# Default value: false
LoadDumpedAssemblies = false
## If enabled, BepInEx will call Debugger.Break() once before loading patched assemblies.
## This can be used with debuggers like dnSpy to install breakpoints into patched assemblies before they are loaded.
# Setting type: Boolean
# Default value: false
BreakBeforeLoadAssemblies = false
[Caching]
## Enable/disable assembly metadata cache
## Enabling this will speed up discovery of plugins and patchers by caching the metadata of all types BepInEx discovers.
# Setting type: Boolean
# Default value: true
EnableAssemblyCache = true
[Detours]
## The native provider to use for managed detours
# Setting type: DetourProvider
# Default value: Default
# Acceptable values: Default, Dobby, Funchook
DetourProviderType = Default
[Harmony.Logger]
## Specifies which Harmony log channels to listen to.
## NOTE: IL channel dumps the whole patch methods, use only when needed!
# Setting type: LogChannel
# Default value: Warn, Error
# Acceptable values: None, Info, IL, Warn, Error, Debug, All
# Multiple values can be set at the same time by separating them with , (e.g. Debug, Warning)
LogChannels = Warn, Error
[IL2CPP]
## Whether to run Il2CppInterop automatically to generate Il2Cpp support assemblies when they are outdated.
## If disabled assemblies in `BepInEx/interop` won't be updated between game or BepInEx updates!
##
# Setting type: Boolean
# Default value: true
UpdateInteropAssemblies = true
## URL to the ZIP of managed Unity base libraries.
## The base libraries are used by Il2CppInterop to generate interop assemblies.
## The URL can include {VERSION} template which will be replaced with the game's Unity engine version.
##
# Setting type: String
# Default value: https://unity.bepinex.dev/libraries/{VERSION}.zip
UnityBaseLibrariesSource = https://unity.bepinex.dev/libraries/{VERSION}.zip
## The RegEx string to pass to Il2CppAssemblyUnhollower for renaming obfuscated names.
## All types and members matching this RegEx will get a name based on their signature,
## resulting in names that persist after game updates.
##
# Setting type: String
# Default value:
UnhollowerDeobfuscationRegex =
## If enabled, Il2CppInterop will use xref to find dead methods and generate CallerCount attributes.
# Setting type: Boolean
# Default value: true
ScanMethodRefs = false
## If enabled, BepInEx will save dummy assemblies generated by an Cpp2IL dumper into BepInEx/dummy.
# Setting type: Boolean
# Default value: false
DumpDummyAssemblies = false
## The path to the folder where IL2CPPInterop assemblies are stored.
## Supports the following placeholders:
## {BepInEx} - Path to the BepInEx folder.
## {ProcessName} - Name of the current process
##
# Setting type: String
# Default value: {BepInEx}
IL2CPPInteropAssembliesPath = {BepInEx}
## Automatically load all interop assemblies right before loading plugins.
## Some plugins may not work properly without this, but it may cause issues in some games.
##
# Setting type: Boolean
# Default value: true
PreloadIL2CPPInteropAssemblies = true
## The path to the IL2CPP metadata file.
## Supports the following placeholders:
## {BepInEx} - Path to the BepInEx folder.
## {ProcessName} - Name of the current process
## {GameDataPath} - Path to the game's Data folder.
##
# Setting type: String
# Default value: {GameDataPath}/il2cpp_data/Metadata/global-metadata.dat
GlobalMetadataPath = {GameDataPath}/il2cpp_data/Metadata/global-metadata.dat
[Logging]
## Enables showing unity log messages in the BepInEx logging system.
# Setting type: Boolean
# Default value: true
UnityLogListening = true
[Logging.Console]
## Enables showing a console for log output.
# Setting type: Boolean
# Default value: true
Enabled = true
## If enabled, will prevent closing the console (either by deleting the close button or in other platform-specific way).
# Setting type: Boolean
# Default value: false
PreventClose = false
## If true, console is set to the Shift-JIS encoding, otherwise UTF-8 encoding.
# Setting type: Boolean
# Default value: false
ShiftJisEncoding = false
## Hints console manager on what handle to assign as StandardOut. Possible values:
## Auto - lets BepInEx decide how to redirect console output
## ConsoleOut - prefer redirecting to console output; if possible, closes original standard output
## StandardOut - prefer redirecting to standard output; if possible, closes console out
##
# Setting type: ConsoleOutRedirectType
# Default value: Auto
# Acceptable values: Auto, ConsoleOut, StandardOut
StandardOutType = Auto
## Which log levels to show in the console output.
# Setting type: LogLevel
# Default value: Fatal, Error, Warning, Message, Info
# Acceptable values: None, Fatal, Error, Warning, Message, Info, Debug, All
# Multiple values can be set at the same time by separating them with , (e.g. Debug, Warning)
LogLevels = Fatal, Error, Warning, Message, Info
[Logging.Disk]
## Appends to the log file instead of overwriting, on game startup.
# Setting type: Boolean
# Default value: false
AppendLog = false
## Enables writing log messages to disk.
# Setting type: Boolean
# Default value: true
Enabled = true
## Only displays the specified log levels in the disk log output.
# Setting type: LogLevel
# Default value: Fatal, Error, Warning, Message, Info
# Acceptable values: None, Fatal, Error, Warning, Message, Info, Debug, All
# Multiple values can be set at the same time by separating them with , (e.g. Debug, Warning)
LogLevels = Fatal, Error, Warning, Message, Info
## If true, instantly writes any received log entries to disk.
## This incurs a major performance hit if a lot of log messages are being written, however it is really useful for debugging crashes.
##
# Setting type: Boolean
# Default value: false
InstantFlushing = false
## The maximum amount of concurrent log files that will be written to disk.
## As one log file is used per open game instance, you may find it necessary to increase this limit when debugging multiple instances at the same time.
##
# Setting type: Int32
# Default value: 5
ConcurrentFileLimit = 5
## Include unity log messages in log file output.
# Setting type: Boolean
# Default value: false
WriteUnityLog = false
[Preloader]
## Specifies which MonoMod backend to use for Harmony patches. Auto uses the best available backend.
## This setting should only be used for development purposes (e.g. debugging in dnSpy). Other code might override this setting.
# Setting type: MonoModBackend
# Default value: auto
# Acceptable values: auto, dynamicmethod, methodbuilder, cecil
HarmonyBackend = auto
## If enabled, BepInEx will save patched assemblies into BepInEx/DumpedAssemblies.
## This can be used by developers to inspect and debug preloader patchers.
# Setting type: Boolean
# Default value: false
DumpAssemblies = false
## If enabled, BepInEx will load patched assemblies from BepInEx/DumpedAssemblies instead of memory.
## This can be used to be able to load patched assemblies into debuggers like dnSpy.
## If set to true, will override DumpAssemblies.
# Setting type: Boolean
# Default value: false
LoadDumpedAssemblies = false
## If enabled, BepInEx will call Debugger.Break() once before loading patched assemblies.
## This can be used with debuggers like dnSpy to install breakpoints into patched assemblies before they are loaded.
# Setting type: Boolean
# Default value: false
BreakBeforeLoadAssemblies = false
@@ -1,15 +1,15 @@
## Settings file was created by EHR
## Plugin GUID: at.duikbo.regioninstall
[General]
## Create an array of regions you want to add/update. To create this array, go to https://impostor.github.io/Impostor/ and put the Regions array from the server file in here
# Setting type: String
# Default value: {\"CurrentRegionIdx\":0,\"Regions\":[]}
Regions = { \"CurrentRegionIdx\": 2, \"Regions\": [ { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Niko-NA\", \"PingServer\": \"https://au-us.niko233.top\", \"Servers\": [ { \"Name\": \"http-1\", \"Ip\": \"https://au-us.niko233.top\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 }, { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Niko-AS\", \"PingServer\": \"https://au-as.niko233.top\", \"Servers\": [ { \"Name\": \"http-1\", \"Ip\": \"https://au-as.niko233.top\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 }, { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Niko-EU\", \"PingServer\": \"https://au-eu.niko233.top\", \"Servers\": [ { \"Name\": \"http-1\", \"Ip\": \"https://au-eu.niko233.top\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 }, { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Modded EU (MEU)\", \"PingServer\": \"https://au-eu.duikbo.at\", \"Servers\": [ { \"Name\": \"Http-1\", \"Ip\": \"https://au-eu.duikbo.at\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 }, { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Modded NA (MNA)\", \"PingServer\": \"https://aumods.org\", \"Servers\": [ { \"Name\": \"Http-1\", \"Ip\": \"https://aumods.org\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 }, { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Modded Asia (MAS)\", \"PingServer\": \"https://au-as.duikbo.at\", \"Servers\": [ { \"Name\": \"Http-1\", \"Ip\": \"https://au-as.duikbo.at\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 } ] }
## Comma-seperated list of region names that should be removed.
# Setting type: String
# Default value:
RemoveRegions = Niko233(NA_US),Niko233(NA_US2),Niko233(AS_CN),Niko233(AS_CN2),NikoCat233(US),NikoCat233(CN),Niko233(AS3),Niko233(NA2),Niko233(EU2),Niko233(AS2),Custom,Niko233(NA),Niko233(EU),Niko233(AS),Niko233(CN),Modded SA (MSA),Niko-CN
## Settings file was created by EHR
## Plugin GUID: at.duikbo.regioninstall
[General]
## Create an array of regions you want to add/update. To create this array, go to https://impostor.github.io/Impostor/ and put the Regions array from the server file in here
# Setting type: String
# Default value: {\"CurrentRegionIdx\":0,\"Regions\":[]}
Regions = { \"CurrentRegionIdx\": 2, \"Regions\": [ { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Niko-NA\", \"PingServer\": \"https://au-us.niko233.top\", \"Servers\": [ { \"Name\": \"http-1\", \"Ip\": \"https://au-us.niko233.top\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 }, { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Niko-AS\", \"PingServer\": \"https://au-as.niko233.top\", \"Servers\": [ { \"Name\": \"http-1\", \"Ip\": \"https://au-as.niko233.top\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 }, { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Niko-EU\", \"PingServer\": \"https://au-eu.niko233.top\", \"Servers\": [ { \"Name\": \"http-1\", \"Ip\": \"https://au-eu.niko233.top\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 }, { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Modded EU (MEU)\", \"PingServer\": \"https://au-eu.duikbo.at\", \"Servers\": [ { \"Name\": \"Http-1\", \"Ip\": \"https://au-eu.duikbo.at\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 }, { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Modded NA (MNA)\", \"PingServer\": \"https://aumods.org\", \"Servers\": [ { \"Name\": \"Http-1\", \"Ip\": \"https://aumods.org\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 }, { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Modded Asia (MAS)\", \"PingServer\": \"https://au-as.duikbo.at\", \"Servers\": [ { \"Name\": \"Http-1\", \"Ip\": \"https://au-as.duikbo.at\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 } ] }
## Comma-seperated list of region names that should be removed.
# Setting type: String
# Default value:
RemoveRegions = Niko233(NA_US),Niko233(NA_US2),Niko233(AS_CN),Niko233(AS_CN2),NikoCat233(US),NikoCat233(CN),Niko233(AS3),Niko233(NA2),Niko233(EU2),Niko233(AS2),Custom,Niko233(NA),Niko233(EU),Niko233(AS),Niko233(CN),Modded SA (MSA),Niko-CN
@@ -2,21 +2,22 @@
[General]
# Enable Doorstop?
enabled = true
enabled=true
# Path to the assembly to load and execute
# NOTE: The entrypoint must be of format `static void Doorstop.Entrypoint.Start()`
target_assembly = BepInEx\core\BepInEx.Unity.IL2CPP.dll
target_assembly=BepInEx\core\BepInEx.Unity.IL2CPP.dll
# If true, Unity's output log is redirected to <current folder>\output_log.txt
redirect_output_log = false
redirect_output_log=false
# Overrides the default boot.config file path
boot_config_override =
boot_config_override=
# If enabled, DOORSTOP_DISABLE env var value is ignored
# USE THIS ONLY WHEN ASKED TO OR YOU KNOW WHAT THIS MEANS
ignore_disable_switch = false
ignore_disable_switch=false
# Options specific to running under Unity Mono runtime
[UnityMono]
@@ -26,25 +27,27 @@ ignore_disable_switch = false
# (e.g. mscorlib is stripped in original game)
# This option causes Mono to seek mscorlib and core libraries from a different folder before Managed
# Original Managed folder is added as a secondary folder in the search path
dll_search_path_override =
# To specify multiple paths, separate them with semicolons (;)
dll_search_path_override=
# If true, Mono debugger server will be enabled
debug_enabled = false
debug_enabled=false
# When debug_enabled is true, specifies the address to use for the debugger server
debug_address = 127.0.0.1:10000
debug_address=127.0.0.1:10000
# If true and debug_enabled is true, Mono debugger server will suspend the game execution until a debugger is attached
debug_suspend = false
debug_suspend=false
# Options sepcific to running under Il2Cpp runtime
[Il2Cpp]
# Path to coreclr.dll that contains the CoreCLR runtime
coreclr_path = dotnet\coreclr.dll
coreclr_path=dotnet\coreclr.dll
# Path to the directory containing the managed core libraries for CoreCLR (mscorlib, System, etc.)
corlib_dir = dotnet
corlib_dir=dotnet
# Environment variables to set for the current game process before the Unity runtime starts.
[Environment]
GC_DISABLE_INCREMENTAL=1
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
4.5.1
+194
View File
@@ -0,0 +1,194 @@
[Caching]
## Enable/disable assembly metadata cache
## Enabling this will speed up discovery of plugins and patchers by caching the metadata of all types BepInEx discovers.
# Setting type: Boolean
# Default value: true
EnableAssemblyCache = true
[Detours]
## The native provider to use for managed detours
# Setting type: DetourProvider
# Default value: Default
# Acceptable values: Default, Dobby, Funchook
DetourProviderType = Default
[Harmony.Logger]
## Specifies which Harmony log channels to listen to.
## NOTE: IL channel dumps the whole patch methods, use only when needed!
# Setting type: LogChannel
# Default value: Warn, Error
# Acceptable values: None, Info, IL, Warn, Error, Debug, All
# Multiple values can be set at the same time by separating them with , (e.g. Debug, Warning)
LogChannels = Warn, Error
[IL2CPP]
## Whether to run Il2CppInterop automatically to generate Il2Cpp support assemblies when they are outdated.
## If disabled assemblies in `BepInEx/interop` won't be updated between game or BepInEx updates!
##
# Setting type: Boolean
# Default value: true
UpdateInteropAssemblies = true
## URL to the ZIP of managed Unity base libraries.
## The base libraries are used by Il2CppInterop to generate interop assemblies.
## The URL can include {VERSION} template which will be replaced with the game's Unity engine version.
##
# Setting type: String
# Default value: https://unity.bepinex.dev/libraries/{VERSION}.zip
UnityBaseLibrariesSource = https://unity.bepinex.dev/libraries/{VERSION}.zip
## The RegEx string to pass to Il2CppAssemblyUnhollower for renaming obfuscated names.
## All types and members matching this RegEx will get a name based on their signature,
## resulting in names that persist after game updates.
##
# Setting type: String
# Default value:
UnhollowerDeobfuscationRegex =
## If enabled, Il2CppInterop will use xref to find dead methods and generate CallerCount attributes.
# Setting type: Boolean
# Default value: true
ScanMethodRefs = false
## If enabled, BepInEx will save dummy assemblies generated by an Cpp2IL dumper into BepInEx/dummy.
# Setting type: Boolean
# Default value: false
DumpDummyAssemblies = false
## The path to the folder where IL2CPPInterop assemblies are stored.
## Supports the following placeholders:
## {BepInEx} - Path to the BepInEx folder.
## {ProcessName} - Name of the current process
##
# Setting type: String
# Default value: {BepInEx}
IL2CPPInteropAssembliesPath = {BepInEx}
## Automatically load all interop assemblies right before loading plugins.
## Some plugins may not work properly without this, but it may cause issues in some games.
##
# Setting type: Boolean
# Default value: true
PreloadIL2CPPInteropAssemblies = true
## The path to the IL2CPP metadata file.
## Supports the following placeholders:
## {BepInEx} - Path to the BepInEx folder.
## {ProcessName} - Name of the current process
## {GameDataPath} - Path to the game's Data folder.
##
# Setting type: String
# Default value: {GameDataPath}/il2cpp_data/Metadata/global-metadata.dat
GlobalMetadataPath = {GameDataPath}/il2cpp_data/Metadata/global-metadata.dat
[Logging]
## Enables showing unity log messages in the BepInEx logging system.
# Setting type: Boolean
# Default value: true
UnityLogListening = true
[Logging.Console]
## Enables showing a console for log output.
# Setting type: Boolean
# Default value: true
Enabled = true
## If enabled, will prevent closing the console (either by deleting the close button or in other platform-specific way).
# Setting type: Boolean
# Default value: false
PreventClose = false
## If true, console is set to the Shift-JIS encoding, otherwise UTF-8 encoding.
# Setting type: Boolean
# Default value: false
ShiftJisEncoding = false
## Hints console manager on what handle to assign as StandardOut. Possible values:
## Auto - lets BepInEx decide how to redirect console output
## ConsoleOut - prefer redirecting to console output; if possible, closes original standard output
## StandardOut - prefer redirecting to standard output; if possible, closes console out
##
# Setting type: ConsoleOutRedirectType
# Default value: Auto
# Acceptable values: Auto, ConsoleOut, StandardOut
StandardOutType = Auto
## Which log levels to show in the console output.
# Setting type: LogLevel
# Default value: Fatal, Error, Warning, Message, Info
# Acceptable values: None, Fatal, Error, Warning, Message, Info, Debug, All
# Multiple values can be set at the same time by separating them with , (e.g. Debug, Warning)
LogLevels = Fatal, Error, Warning, Message, Info
[Logging.Disk]
## Appends to the log file instead of overwriting, on game startup.
# Setting type: Boolean
# Default value: false
AppendLog = false
## Enables writing log messages to disk.
# Setting type: Boolean
# Default value: true
Enabled = true
## Only displays the specified log levels in the disk log output.
# Setting type: LogLevel
# Default value: Fatal, Error, Warning, Message, Info
# Acceptable values: None, Fatal, Error, Warning, Message, Info, Debug, All
# Multiple values can be set at the same time by separating them with , (e.g. Debug, Warning)
LogLevels = Fatal, Error, Warning, Message, Info
## If true, instantly writes any received log entries to disk.
## This incurs a major performance hit if a lot of log messages are being written, however it is really useful for debugging crashes.
##
# Setting type: Boolean
# Default value: false
InstantFlushing = false
## The maximum amount of concurrent log files that will be written to disk.
## As one log file is used per open game instance, you may find it necessary to increase this limit when debugging multiple instances at the same time.
##
# Setting type: Int32
# Default value: 5
ConcurrentFileLimit = 5
## Include unity log messages in log file output.
# Setting type: Boolean
# Default value: false
WriteUnityLog = false
[Preloader]
## Specifies which MonoMod backend to use for Harmony patches. Auto uses the best available backend.
## This setting should only be used for development purposes (e.g. debugging in dnSpy). Other code might override this setting.
# Setting type: MonoModBackend
# Default value: auto
# Acceptable values: auto, dynamicmethod, methodbuilder, cecil
HarmonyBackend = auto
## If enabled, BepInEx will save patched assemblies into BepInEx/DumpedAssemblies.
## This can be used by developers to inspect and debug preloader patchers.
# Setting type: Boolean
# Default value: false
DumpAssemblies = false
## If enabled, BepInEx will load patched assemblies from BepInEx/DumpedAssemblies instead of memory.
## This can be used to be able to load patched assemblies into debuggers like dnSpy.
## If set to true, will override DumpAssemblies.
# Setting type: Boolean
# Default value: false
LoadDumpedAssemblies = false
## If enabled, BepInEx will call Debugger.Break() once before loading patched assemblies.
## This can be used with debuggers like dnSpy to install breakpoints into patched assemblies before they are loaded.
# Setting type: Boolean
# Default value: false
BreakBeforeLoadAssemblies = false
@@ -0,0 +1,15 @@
## Settings file was created by EHR
## Plugin GUID: at.duikbo.regioninstall
[General]
## Create an array of regions you want to add/update. To create this array, go to https://impostor.github.io/Impostor/ and put the Regions array from the server file in here
# Setting type: String
# Default value: {\"CurrentRegionIdx\":0,\"Regions\":[]}
Regions = { \"CurrentRegionIdx\": 2, \"Regions\": [ { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Niko-NA\", \"PingServer\": \"https://au-us.niko233.top\", \"Servers\": [ { \"Name\": \"http-1\", \"Ip\": \"https://au-us.niko233.top\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 }, { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Niko-AS\", \"PingServer\": \"https://au-as.niko233.top\", \"Servers\": [ { \"Name\": \"http-1\", \"Ip\": \"https://au-as.niko233.top\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 }, { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Niko-EU\", \"PingServer\": \"https://au-eu.niko233.top\", \"Servers\": [ { \"Name\": \"http-1\", \"Ip\": \"https://au-eu.niko233.top\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 }, { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Modded EU (MEU)\", \"PingServer\": \"https://au-eu.duikbo.at\", \"Servers\": [ { \"Name\": \"Http-1\", \"Ip\": \"https://au-eu.duikbo.at\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 }, { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Modded NA (MNA)\", \"PingServer\": \"https://aumods.org\", \"Servers\": [ { \"Name\": \"Http-1\", \"Ip\": \"https://aumods.org\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 }, { \"$type\": \"StaticHttpRegionInfo, Assembly-CSharp\", \"Name\": \"Modded Asia (MAS)\", \"PingServer\": \"https://au-as.duikbo.at\", \"Servers\": [ { \"Name\": \"Http-1\", \"Ip\": \"https://au-as.duikbo.at\", \"Port\": 443, \"UseDtls\": false, \"Players\": 0, \"ConnectionFailures\": 0 } ], \"TargetServer\": null, \"TranslateName\": 1003 } ] }
## Comma-seperated list of region names that should be removed.
# Setting type: String
# Default value:
RemoveRegions = Niko233(NA_US),Niko233(NA_US2),Niko233(AS_CN),Niko233(AS_CN2),NikoCat233(US),NikoCat233(CN),Niko233(AS3),Niko233(NA2),Niko233(EU2),Niko233(AS2),Custom,Niko233(NA),Niko233(EU),Niko233(AS),Niko233(CN),Modded SA (MSA),Niko-CN
+53
View File
@@ -0,0 +1,53 @@
# General options for Unity Doorstop
[General]
# Enable Doorstop?
enabled=true
# Path to the assembly to load and execute
# NOTE: The entrypoint must be of format `static void Doorstop.Entrypoint.Start()`
target_assembly=BepInEx\core\BepInEx.Unity.IL2CPP.dll
# If true, Unity's output log is redirected to <current folder>\output_log.txt
redirect_output_log=false
# Overrides the default boot.config file path
boot_config_override=
# If enabled, DOORSTOP_DISABLE env var value is ignored
# USE THIS ONLY WHEN ASKED TO OR YOU KNOW WHAT THIS MEANS
ignore_disable_switch=false
# Options specific to running under Unity Mono runtime
[UnityMono]
# Overrides default Mono DLL search path
# Sometimes it is needed to instruct Mono to seek its assemblies from a different path
# (e.g. mscorlib is stripped in original game)
# This option causes Mono to seek mscorlib and core libraries from a different folder before Managed
# Original Managed folder is added as a secondary folder in the search path
# To specify multiple paths, separate them with semicolons (;)
dll_search_path_override=
# If true, Mono debugger server will be enabled
debug_enabled=false
# When debug_enabled is true, specifies the address to use for the debugger server
debug_address=127.0.0.1:10000
# If true and debug_enabled is true, Mono debugger server will suspend the game execution until a debugger is attached
debug_suspend=false
# Options sepcific to running under Il2Cpp runtime
[Il2Cpp]
# Path to coreclr.dll that contains the CoreCLR runtime
coreclr_path=dotnet\coreclr.dll
# Path to the directory containing the managed core libraries for CoreCLR (mscorlib, System, etc.)
corlib_dir=dotnet
# Environment variables to set for the current game process before the Unity runtime starts.
[Environment]
GC_DISABLE_INCREMENTAL=1
Binary file not shown.
Binary file not shown.