Merge into master

This commit is contained in:
BruceChen 2022-12-06 20:32:46 +08:00
commit 892999ac98
155 changed files with 10911 additions and 9860 deletions

View file

@ -1,151 +0,0 @@
name: Build MCC
on:
workflow_dispatch:
env:
PROJECT: "MinecraftClient"
target-version: "net6.0"
compile-flags: "--self-contained=true -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:DebugType=None"
jobs:
Build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
submodules: 'true'
- name: Sync translations from crowdin
uses: crowdin/github-action@1.5.0
with:
upload_translations: true
download_translations: true
localization_branch_name: l10n_master
create_pull_request: false
base_path: ${{ github.workspace }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_TOKEN }}
- name: Setup Project Path
run: |
echo project-path=${{ github.workspace }}/${{ env.PROJECT }} >> $GITHUB_ENV
- name: Setup Output Paths
run: |
echo win-x64-out-path=${{ env.project-path }}/bin/Release/${{ env.target-version }}/win-x64/publish/ >> $GITHUB_ENV
echo win-x86-out-path=${{ env.project-path }}/bin/Release/${{ env.target-version }}/win-x86/publish/ >> $GITHUB_ENV
echo linux-out-path=${{ env.project-path }}/bin/Release/${{ env.target-version }}/linux-x64/publish/ >> $GITHUB_ENV
echo osx-out-path=${{ env.project-path }}/bin/Release/${{ env.target-version }}/osx-x64/publish/ >> $GITHUB_ENV
echo linux-arm64-out-path=${{ env.project-path }}/bin/Release/${{ env.target-version }}/linux-arm64/publish/ >> $GITHUB_ENV
- name: Setup .NET SDK
uses: actions/setup-dotnet@v2.1.0
- name: Get Version DateTime
id: date-version
uses: nanzm/get-time-action@v1.1
with:
timeZone: 0
format: 'YYYY-MM-DD'
- name: VersionInfo
run: |
COMMIT=$(echo ${{ github.sha }} | cut -c 1-7)
echo '' >> ${{ env.project-path }}/Properties/AssemblyInfo.cs
echo "[assembly: AssemblyConfiguration(\"GitHub build ${{ github.run_number }}, built on ${{ steps.date-version.outputs.time }} from commit $COMMIT\")]" >> ${{ env.project-path }}/Properties/AssemblyInfo.cs
- name: Build for Windows x64
run: dotnet publish ${{ env.project-path }}.sln -f ${{ env.target-version }} -r win-x64 ${{ env.compile-flags }}
- name: Zip Windows x64 Build
run: zip -qq -r windows-x64.zip *
working-directory: ${{ env.win-x64-out-path }}
- name: Build for Windows x86
run: dotnet publish ${{ env.project-path }}.sln -f ${{ env.target-version }} -r win-x86 ${{ env.compile-flags }}
- name: Zip Windows x86 Build
run: zip -qq -r windows-x86.zip *
working-directory: ${{ env.win-x86-out-path }}
- name: Build for Linux
run: dotnet publish ${{ env.project-path }}.sln -f ${{ env.target-version }} -r linux-x64 ${{ env.compile-flags }}
- name: Zip Linux Build
run: zip -qq -r linux.zip *
working-directory: ${{ env.linux-out-path }}
- name: Build for ARM64 Linux
run: dotnet publish ${{ env.project-path }}.sln -f ${{ env.target-version }} -r linux-arm64 ${{ env.compile-flags }}
- name: Zip ARM64 Linux Build
run: zip -qq -r linux-arm64.zip *
working-directory: ${{ env.linux-arm64-out-path }}
- name: Build for OSX
run: dotnet publish ${{ env.project-path }}.sln -f ${{ env.target-version }} -r osx-x64 ${{ env.compile-flags }}
- name: Zip OSX Build
run: zip -qq -r osx.zip *
working-directory: ${{ env.osx-out-path }}
- name: Get Release DateTime
id: date-release
uses: nanzm/get-time-action@v1.1
with:
timeZone: 0
format: 'YYYYMMDD'
- name: Windows x64 Release
uses: tix-factory/release-manager@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
mode: uploadReleaseAsset
filePath: ${{ env.win-x64-out-path }}windows-x64.zip
assetName: ${{ env.PROJECT }}-windows-x64.zip
tag: ${{ format('{0}-{1}', steps.date-release.outputs.time, github.run_number) }}
- name: Windows x86 Release
uses: tix-factory/release-manager@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
mode: uploadReleaseAsset
filePath: ${{ env.win-x86-out-path }}windows-x86.zip
assetName: ${{ env.PROJECT }}-windows-x86.zip
tag: ${{ format('{0}-{1}', steps.date-release.outputs.time, github.run_number) }}
- name: Linux Release
uses: tix-factory/release-manager@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
mode: uploadReleaseAsset
filePath: ${{ env.linux-out-path }}linux.zip
assetName: ${{ env.PROJECT }}-linux.zip
tag: ${{ format('{0}-{1}', steps.date-release.outputs.time, github.run_number) }}
- name: Linux ARM64 Release
uses: tix-factory/release-manager@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
mode: uploadReleaseAsset
filePath: ${{ env.linux-arm64-out-path }}linux-arm64.zip
assetName: ${{ env.PROJECT }}-linux-arm64.zip
tag: ${{ format('{0}-{1}', steps.date-release.outputs.time, github.run_number) }}
- name: OSX Release
uses: tix-factory/release-manager@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
mode: uploadReleaseAsset
filePath: ${{ env.osx-out-path }}osx.zip
assetName: ${{ env.PROJECT }}-osx.zip
tag: ${{ format('{0}-{1}', steps.date-release.outputs.time, github.run_number) }}

View file

@ -28,11 +28,13 @@ jobs:
- name: Download translations from crowdin - name: Download translations from crowdin
uses: crowdin/github-action@1.5.0 uses: crowdin/github-action@1.5.0
with: with:
upload_translations: true upload_sources: true
upload_translations: false
download_translations: true download_translations: true
localization_branch_name: l10n_master localization_branch_name: l10n_master
create_pull_request: false create_pull_request: false
push_translations: false
base_path: ${{ github.workspace }} base_path: ${{ github.workspace }}
env: env:

View file

@ -1,6 +1,8 @@
name: Build Documents name: Build Documents
on: on:
schedule:
- cron: '45 0 * * *'
workflow_dispatch: workflow_dispatch:
jobs: jobs:
@ -18,11 +20,13 @@ jobs:
- name: Sync translations from crowdin - name: Sync translations from crowdin
uses: crowdin/github-action@1.5.0 uses: crowdin/github-action@1.5.0
with: with:
upload_translations: true upload_sources: true
upload_translations: false
download_translations: true download_translations: true
localization_branch_name: l10n_master localization_branch_name: l10n_master
create_pull_request: false create_pull_request: false
push_translations: false
base_path: ${{ github.workspace }} base_path: ${{ github.workspace }}
env: env:

View file

@ -18,11 +18,13 @@ jobs:
- name: Sync translations from crowdin - name: Sync translations from crowdin
uses: crowdin/github-action@1.5.0 uses: crowdin/github-action@1.5.0
with: with:
upload_translations: true upload_sources: true
upload_translations: false
download_translations: true download_translations: true
localization_branch_name: l10n_master localization_branch_name: l10n_master
create_pull_request: false create_pull_request: false
push_translations: false
base_path: ${{ github.workspace }} base_path: ${{ github.workspace }}
env: env:

View file

@ -1,4 +1,4 @@
// GZipStream.cs // GZipStream.cs
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// //
// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. // Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.

View file

@ -1,4 +1,4 @@
// ZlibBaseStream.cs // ZlibBaseStream.cs
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// //
// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. // Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.

View file

@ -26,7 +26,8 @@ Global
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
RESX_ShowErrorsInErrorList = False RESX_SortFileContentOnSave = True
SolutionGuid = {6DED60F4-9CF4-4DB3-8966-582B2EBE8487} SolutionGuid = {6DED60F4-9CF4-4DB3-8966-582B2EBE8487}
RESX_ShowErrorsInErrorList = False
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View file

@ -20,28 +20,28 @@ namespace MinecraftClient.ChatBots
public bool Enabled = false; public bool Enabled = false;
[TomlInlineComment("$config.ChatBot.Alerts.Beep_Enabled$")] [TomlInlineComment("$ChatBot.Alerts.Beep_Enabled$")]
public bool Beep_Enabled = true; public bool Beep_Enabled = true;
[TomlInlineComment("$config.ChatBot.Alerts.Trigger_By_Words$")] [TomlInlineComment("$ChatBot.Alerts.Trigger_By_Words$")]
public bool Trigger_By_Words = false; public bool Trigger_By_Words = false;
[TomlInlineComment("$config.ChatBot.Alerts.Trigger_By_Rain$")] [TomlInlineComment("$ChatBot.Alerts.Trigger_By_Rain$")]
public bool Trigger_By_Rain = false; public bool Trigger_By_Rain = false;
[TomlInlineComment("$config.ChatBot.Alerts.Trigger_By_Thunderstorm$")] [TomlInlineComment("$ChatBot.Alerts.Trigger_By_Thunderstorm$")]
public bool Trigger_By_Thunderstorm = false; public bool Trigger_By_Thunderstorm = false;
[TomlInlineComment("$config.ChatBot.Alerts.Log_To_File$")] [TomlInlineComment("$ChatBot.Alerts.Log_To_File$")]
public bool Log_To_File = false; public bool Log_To_File = false;
[TomlInlineComment("$config.ChatBot.Alerts.Log_File$")] [TomlInlineComment("$ChatBot.Alerts.Log_File$")]
public string Log_File = @"alerts-log.txt"; public string Log_File = @"alerts-log.txt";
[TomlPrecedingComment("$config.ChatBot.Alerts.Matches$")] [TomlPrecedingComment("$ChatBot.Alerts.Matches$")]
public string[] Matches = new string[] { "Yourname", " whispers ", "-> me", "admin", ".com" }; public string[] Matches = new string[] { "Yourname", " whispers ", "-> me", "admin", ".com" };
[TomlPrecedingComment("$config.ChatBot.Alerts.Excludes$")] [TomlPrecedingComment("$ChatBot.Alerts.Excludes$")]
public string[] Excludes = new string[] { "myserver.com", "Yourname>:", "Player Yourname", "Yourname joined", "Yourname left", "[Lockette] (Admin)", " Yourname:", "Yourname is" }; public string[] Excludes = new string[] { "myserver.com", "Yourname>:", "Player Yourname", "Yourname joined", "Yourname left", "[Lockette] (Admin)", " Yourname:", "Yourname is" };
public void OnSettingUpdate() public void OnSettingUpdate()
@ -124,7 +124,7 @@ namespace MinecraftClient.ChatBots
Console.Beep(); Console.Beep();
Console.Beep(); Console.Beep();
} }
LogToConsole(Translations.bot_alerts_start_rain); LogToConsole("§c" + Translations.bot_alerts_start_rain);
} }
} }
else if (curRainLevel >= threshold && level < threshold) else if (curRainLevel >= threshold && level < threshold)
@ -135,7 +135,7 @@ namespace MinecraftClient.ChatBots
{ {
Console.Beep(); Console.Beep();
} }
LogToConsole(Translations.bot_alerts_end_rain); LogToConsole("§c" + Translations.bot_alerts_end_rain);
} }
} }
curRainLevel = level; curRainLevel = level;
@ -152,7 +152,7 @@ namespace MinecraftClient.ChatBots
Console.Beep(); Console.Beep();
Console.Beep(); Console.Beep();
} }
LogToConsole(Translations.bot_alerts_start_thunderstorm); LogToConsole("§c" + Translations.bot_alerts_start_thunderstorm);
} }
} }
else if (curThunderLevel >= threshold && level < threshold) else if (curThunderLevel >= threshold && level < threshold)
@ -163,7 +163,7 @@ namespace MinecraftClient.ChatBots
{ {
Console.Beep(); Console.Beep();
} }
LogToConsole(Translations.bot_alerts_end_thunderstorm); LogToConsole("§c" + Translations.bot_alerts_end_thunderstorm);
} }
} }
curThunderLevel = level; curThunderLevel = level;

View file

@ -23,22 +23,22 @@ namespace MinecraftClient.ChatBots
public bool Enabled = false; public bool Enabled = false;
[TomlInlineComment("$config.ChatBot.AntiAfk.Delay$")] [TomlInlineComment("$ChatBot.AntiAfk.Delay$")]
public Range Delay = new(60); public Range Delay = new(60);
[TomlInlineComment("$config.ChatBot.AntiAfk.Command$")] [TomlInlineComment("$ChatBot.AntiAfk.Command$")]
public string Command = "/ping"; public string Command = "/ping";
[TomlInlineComment("$config.ChatBot.AntiAfk.Use_Sneak$")] [TomlInlineComment("$ChatBot.AntiAfk.Use_Sneak$")]
public bool Use_Sneak = false; public bool Use_Sneak = false;
[TomlInlineComment("$config.ChatBot.AntiAfk.Use_Terrain_Handling$")] [TomlInlineComment("$ChatBot.AntiAfk.Use_Terrain_Handling$")]
public bool Use_Terrain_Handling = false; public bool Use_Terrain_Handling = false;
[TomlInlineComment("$config.ChatBot.AntiAfk.Walk_Range$")] [TomlInlineComment("$ChatBot.AntiAfk.Walk_Range$")]
public int Walk_Range = 5; public int Walk_Range = 5;
[TomlInlineComment("$config.ChatBot.AntiAfk.Walk_Retries$")] [TomlInlineComment("$ChatBot.AntiAfk.Walk_Retries$")]
public int Walk_Retries = 20; public int Walk_Retries = 20;
public void OnSettingUpdate() public void OnSettingUpdate()
@ -93,7 +93,7 @@ namespace MinecraftClient.ChatBots
count = 0; count = 0;
} }
public override void Initialize(CommandDispatcher<CmdResult> dispatcher) public override void Initialize()
{ {
if (Config.Use_Terrain_Handling) if (Config.Use_Terrain_Handling)
{ {

View file

@ -23,28 +23,28 @@ namespace MinecraftClient.ChatBots
public bool Enabled = false; public bool Enabled = false;
[TomlInlineComment("$config.ChatBot.AutoAttack.Mode$")] [TomlInlineComment("$ChatBot.AutoAttack.Mode$")]
public AttackMode Mode = AttackMode.single; public AttackMode Mode = AttackMode.single;
[TomlInlineComment("$config.ChatBot.AutoAttack.Priority$")] [TomlInlineComment("$ChatBot.AutoAttack.Priority$")]
public PriorityType Priority = PriorityType.distance; public PriorityType Priority = PriorityType.distance;
[TomlInlineComment("$config.ChatBot.AutoAttack.Cooldown_Time$")] [TomlInlineComment("$ChatBot.AutoAttack.Cooldown_Time$")]
public CooldownConfig Cooldown_Time = new(false, 1.0); public CooldownConfig Cooldown_Time = new(false, 1.0);
[TomlInlineComment("$config.ChatBot.AutoAttack.Interaction$")] [TomlInlineComment("$ChatBot.AutoAttack.Interaction$")]
public InteractType Interaction = InteractType.Attack; public InteractType Interaction = InteractType.Attack;
[TomlInlineComment("$config.ChatBot.AutoAttack.Attack_Hostile$")] [TomlInlineComment("$ChatBot.AutoAttack.Attack_Hostile$")]
public bool Attack_Hostile = true; public bool Attack_Hostile = true;
[TomlInlineComment("$config.ChatBot.AutoAttack.Attack_Passive$")] [TomlInlineComment("$ChatBot.AutoAttack.Attack_Passive$")]
public bool Attack_Passive = false; public bool Attack_Passive = false;
[TomlInlineComment("$config.ChatBot.AutoAttack.List_Mode$")] [TomlInlineComment("$ChatBot.AutoAttack.List_Mode$")]
public ListType List_Mode = ListType.whitelist; public ListType List_Mode = ListType.whitelist;
[TomlInlineComment("$config.ChatBot.AutoAttack.Entites_List$")] [TomlInlineComment("$ChatBot.AutoAttack.Entites_List$")]
public List<EntityType> Entites_List = new() { EntityType.Zombie, EntityType.Cow }; public List<EntityType> Entites_List = new() { EntityType.Zombie, EntityType.Cow };
public void OnSettingUpdate() public void OnSettingUpdate()
@ -112,7 +112,7 @@ namespace MinecraftClient.ChatBots
attackPassive = Config.Attack_Passive; attackPassive = Config.Attack_Passive;
} }
public override void Initialize(CommandDispatcher<CmdResult> dispatcher) public override void Initialize()
{ {
if (!GetEntityHandlingEnabled()) if (!GetEntityHandlingEnabled())
{ {

View file

@ -28,13 +28,13 @@ namespace MinecraftClient.ChatBots
public bool Enabled = false; public bool Enabled = false;
[TomlInlineComment("$config.ChatBot.AutoCraft.CraftingTable$")] [TomlInlineComment("$ChatBot.AutoCraft.CraftingTable$")]
public LocationConfig CraftingTable = new(123, 65, 456); public LocationConfig CraftingTable = new(123, 65, 456);
[TomlInlineComment("$config.ChatBot.AutoCraft.OnFailure$")] [TomlInlineComment("$ChatBot.AutoCraft.OnFailure$")]
public OnFailConfig OnFailure = OnFailConfig.abort; public OnFailConfig OnFailure = OnFailConfig.abort;
[TomlPrecedingComment("$config.ChatBot.AutoCraft.Recipes$")] [TomlPrecedingComment("$ChatBot.AutoCraft.Recipes$")]
public RecipeConfig[] Recipes = new RecipeConfig[] public RecipeConfig[] Recipes = new RecipeConfig[]
{ {
new RecipeConfig( new RecipeConfig(
@ -286,7 +286,7 @@ namespace MinecraftClient.ChatBots
} }
} }
public override void Initialize(CommandDispatcher<CmdResult> dispatcher) public override void Initialize()
{ {
if (!GetInventoryEnabled()) if (!GetInventoryEnabled())
{ {
@ -296,7 +296,7 @@ namespace MinecraftClient.ChatBots
return; return;
} }
dispatcher.Register(l => l.Literal("help") Handler.dispatcher.Register(l => l.Literal("help")
.Then(l => l.Literal(CommandName) .Then(l => l.Literal(CommandName)
.Executes(r => OnCommandHelp(r.Source, string.Empty)) .Executes(r => OnCommandHelp(r.Source, string.Empty))
.Then(l => l.Literal("list") .Then(l => l.Literal("list")
@ -310,7 +310,7 @@ namespace MinecraftClient.ChatBots
) )
); );
dispatcher.Register(l => l.Literal(CommandName) Handler.dispatcher.Register(l => l.Literal(CommandName)
.Then(l => l.Literal("list") .Then(l => l.Literal("list")
.Executes(r => OnCommandList(r.Source))) .Executes(r => OnCommandList(r.Source)))
.Then(l => l.Literal("start") .Then(l => l.Literal("start")
@ -319,14 +319,14 @@ namespace MinecraftClient.ChatBots
.Then(l => l.Literal("stop") .Then(l => l.Literal("stop")
.Executes(r => OnCommandStop(r.Source))) .Executes(r => OnCommandStop(r.Source)))
.Then(l => l.Literal("_help") .Then(l => l.Literal("_help")
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CommandName))) .Redirect(Handler.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
); );
} }
public override void OnUnload(CommandDispatcher<CmdResult> dispatcher) public override void OnUnload()
{ {
dispatcher.Unregister(CommandName); Handler.dispatcher.Unregister(CommandName);
dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName); Handler.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
} }
private int OnCommandHelp(CmdResult r, string? cmd) private int OnCommandHelp(CmdResult r, string? cmd)
@ -339,7 +339,7 @@ namespace MinecraftClient.ChatBots
"stop" => Translations.bot_autoCraft_help_stop, "stop" => Translations.bot_autoCraft_help_stop,
"help" => Translations.bot_autoCraft_help_help, "help" => Translations.bot_autoCraft_help_help,
_ => string.Format(Translations.bot_autoCraft_available_cmd, "load, list, reload, resetcfg, start, stop, help") _ => string.Format(Translations.bot_autoCraft_available_cmd, "load, list, reload, resetcfg, start, stop, help")
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false), + '\n' + Handler.dispatcher.GetAllUsageString(CommandName, false),
#pragma warning restore format // @formatter:on #pragma warning restore format // @formatter:on
}); });
} }

View file

@ -26,36 +26,36 @@ namespace MinecraftClient.ChatBots
public bool Enabled = false; public bool Enabled = false;
[NonSerialized] [NonSerialized]
[TomlInlineComment("$config.ChatBot.AutoDig.Auto_Tool_Switch$")] [TomlInlineComment("$ChatBot.AutoDig.Auto_Tool_Switch$")]
public bool Auto_Tool_Switch = false; public bool Auto_Tool_Switch = false;
[NonSerialized] [NonSerialized]
[TomlInlineComment("$config.ChatBot.AutoDig.Durability_Limit$")] [TomlInlineComment("$ChatBot.AutoDig.Durability_Limit$")]
public int Durability_Limit = 2; public int Durability_Limit = 2;
[NonSerialized] [NonSerialized]
[TomlInlineComment("$config.ChatBot.AutoDig.Drop_Low_Durability_Tools$")] [TomlInlineComment("$ChatBot.AutoDig.Drop_Low_Durability_Tools$")]
public bool Drop_Low_Durability_Tools = false; public bool Drop_Low_Durability_Tools = false;
[TomlInlineComment("$config.ChatBot.AutoDig.Mode$")] [TomlInlineComment("$ChatBot.AutoDig.Mode$")]
public ModeType Mode = ModeType.lookat; public ModeType Mode = ModeType.lookat;
[TomlPrecedingComment("$config.ChatBot.AutoDig.Locations$")] [TomlPrecedingComment("$ChatBot.AutoDig.Locations$")]
public Coordination[] Locations = new Coordination[] { new(123.5, 64, 234.5), new(124.5, 63, 235.5) }; public Coordination[] Locations = new Coordination[] { new(123.5, 64, 234.5), new(124.5, 63, 235.5) };
[TomlInlineComment("$config.ChatBot.AutoDig.Location_Order$")] [TomlInlineComment("$ChatBot.AutoDig.Location_Order$")]
public OrderType Location_Order = OrderType.distance; public OrderType Location_Order = OrderType.distance;
[TomlInlineComment("$config.ChatBot.AutoDig.Auto_Start_Delay$")] [TomlInlineComment("$ChatBot.AutoDig.Auto_Start_Delay$")]
public double Auto_Start_Delay = 3.0; public double Auto_Start_Delay = 3.0;
[TomlInlineComment("$config.ChatBot.AutoDig.Dig_Timeout$")] [TomlInlineComment("$ChatBot.AutoDig.Dig_Timeout$")]
public double Dig_Timeout = 60.0; public double Dig_Timeout = 60.0;
[TomlInlineComment("$config.ChatBot.AutoDig.Log_Block_Dig$")] [TomlInlineComment("$ChatBot.AutoDig.Log_Block_Dig$")]
public bool Log_Block_Dig = true; public bool Log_Block_Dig = true;
[TomlInlineComment("$config.ChatBot.AutoDig.List_Type$")] [TomlInlineComment("$ChatBot.AutoDig.List_Type$")]
public ListType List_Type = ListType.whitelist; public ListType List_Type = ListType.whitelist;
public List<Material> Blocks = new() { Material.Cobblestone, Material.Stone }; public List<Material> Blocks = new() { Material.Cobblestone, Material.Stone };
@ -110,7 +110,7 @@ namespace MinecraftClient.ChatBots
Stopping, Stopping,
} }
public override void Initialize(CommandDispatcher<CmdResult> dispatcher) public override void Initialize()
{ {
if (!GetTerrainEnabled()) if (!GetTerrainEnabled())
{ {
@ -124,7 +124,7 @@ namespace MinecraftClient.ChatBots
if (!inventoryEnabled && Config.Auto_Tool_Switch) if (!inventoryEnabled && Config.Auto_Tool_Switch)
LogToConsole(Translations.bot_autodig_no_inv_handle); LogToConsole(Translations.bot_autodig_no_inv_handle);
dispatcher.Register(l => l.Literal("help") Handler.dispatcher.Register(l => l.Literal("help")
.Then(l => l.Literal(CommandName) .Then(l => l.Literal(CommandName)
.Executes(r => OnCommandHelp(r.Source, string.Empty)) .Executes(r => OnCommandHelp(r.Source, string.Empty))
.Then(l => l.Literal("start") .Then(l => l.Literal("start")
@ -136,25 +136,25 @@ namespace MinecraftClient.ChatBots
) )
); );
var cmd = dispatcher.Register(l => l.Literal(CommandName) var cmd = Handler.dispatcher.Register(l => l.Literal(CommandName)
.Then(l => l.Literal("start") .Then(l => l.Literal("start")
.Executes(r => OnCommandStart(r.Source))) .Executes(r => OnCommandStart(r.Source)))
.Then(l => l.Literal("stop") .Then(l => l.Literal("stop")
.Executes(r => OnCommandStop(r.Source))) .Executes(r => OnCommandStop(r.Source)))
.Then(l => l.Literal("_help") .Then(l => l.Literal("_help")
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CommandName))) .Redirect(Handler.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
); );
dispatcher.Register(l => l.Literal("digbot") Handler.dispatcher.Register(l => l.Literal("digbot")
.Redirect(cmd) .Redirect(cmd)
); );
} }
public override void OnUnload(CommandDispatcher<CmdResult> dispatcher) public override void OnUnload()
{ {
dispatcher.Unregister("digbot"); Handler.dispatcher.Unregister("digbot");
dispatcher.Unregister(CommandName); Handler.dispatcher.Unregister(CommandName);
dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName); Handler.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
} }
private int OnCommandHelp(CmdResult r, string? cmd) private int OnCommandHelp(CmdResult r, string? cmd)
@ -166,7 +166,7 @@ namespace MinecraftClient.ChatBots
"stop" => Translations.bot_autodig_help_stop, "stop" => Translations.bot_autodig_help_stop,
"help" => Translations.bot_autodig_help_help, "help" => Translations.bot_autodig_help_help,
_ => string.Format(Translations.bot_autodig_available_cmd, "start, stop, help") _ => string.Format(Translations.bot_autodig_available_cmd, "start, stop, help")
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false), + '\n' + Handler.dispatcher.GetAllUsageString(CommandName, false),
#pragma warning restore format // @formatter:on #pragma warning restore format // @formatter:on
}); });
} }

View file

@ -26,7 +26,7 @@ namespace MinecraftClient.ChatBots
public bool Enabled = false; public bool Enabled = false;
[TomlInlineComment("$config.ChatBot.AutoDrop.Mode$")] [TomlInlineComment("$ChatBot.AutoDrop.Mode$")]
public DropMode Mode = DropMode.include; public DropMode Mode = DropMode.include;
public List<ItemType> Items = new() { ItemType.Cobblestone, ItemType.Dirt }; public List<ItemType> Items = new() { ItemType.Cobblestone, ItemType.Dirt };
@ -45,7 +45,7 @@ namespace MinecraftClient.ChatBots
private readonly int updateDebounceValue = 2; private readonly int updateDebounceValue = 2;
private int inventoryUpdated = -1; private int inventoryUpdated = -1;
public override void Initialize(CommandDispatcher<CmdResult> dispatcher) public override void Initialize()
{ {
if (!GetInventoryEnabled()) if (!GetInventoryEnabled())
{ {
@ -55,7 +55,7 @@ namespace MinecraftClient.ChatBots
return; return;
} }
dispatcher.Register(l => l.Literal("help") Handler.dispatcher.Register(l => l.Literal("help")
.Then(l => l.Literal(CommandName) .Then(l => l.Literal(CommandName)
.Executes(r => OnCommandHelp(r.Source, string.Empty)) .Executes(r => OnCommandHelp(r.Source, string.Empty))
.Then(l => l.Literal("add") .Then(l => l.Literal("add")
@ -67,7 +67,7 @@ namespace MinecraftClient.ChatBots
) )
); );
dispatcher.Register(l => l.Literal(CommandName) Handler.dispatcher.Register(l => l.Literal(CommandName)
.Then(l => l.Literal("on") .Then(l => l.Literal("on")
.Executes(r => OnCommandEnable(r.Source, true))) .Executes(r => OnCommandEnable(r.Source, true)))
.Then(l => l.Literal("off") .Then(l => l.Literal("off")
@ -88,14 +88,14 @@ namespace MinecraftClient.ChatBots
.Then(l => l.Literal("everything") .Then(l => l.Literal("everything")
.Executes(r => OnCommandMode(r.Source, DropMode.everything)))) .Executes(r => OnCommandMode(r.Source, DropMode.everything))))
.Then(l => l.Literal("_help") .Then(l => l.Literal("_help")
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CommandName))) .Redirect(Handler.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
); );
} }
public override void OnUnload(CommandDispatcher<CmdResult> dispatcher) public override void OnUnload()
{ {
dispatcher.Unregister(CommandName); Handler.dispatcher.Unregister(CommandName);
dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName); Handler.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
} }
private int OnCommandHelp(CmdResult r, string? cmd) private int OnCommandHelp(CmdResult r, string? cmd)
@ -107,7 +107,7 @@ namespace MinecraftClient.ChatBots
"remove" => Translations.cmd_inventory_help_usage + ": remove <item name>", "remove" => Translations.cmd_inventory_help_usage + ": remove <item name>",
"mode" => Translations.bot_autoDrop_unknown_mode, "mode" => Translations.bot_autoDrop_unknown_mode,
_ => string.Format(Translations.general_available_cmd, "on, off, add, remove, list, mode") _ => string.Format(Translations.general_available_cmd, "on, off, add, remove, list, mode")
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false), + '\n' + Handler.dispatcher.GetAllUsageString(CommandName, false),
#pragma warning restore format // @formatter:on #pragma warning restore format // @formatter:on
}); });
} }

View file

@ -32,43 +32,43 @@ namespace MinecraftClient.ChatBots
public bool Enabled = false; public bool Enabled = false;
[TomlInlineComment("$config.ChatBot.AutoFishing.Antidespawn$")] [TomlInlineComment("$ChatBot.AutoFishing.Antidespawn$")]
public bool Antidespawn = false; public bool Antidespawn = false;
[TomlInlineComment("$config.ChatBot.AutoFishing.Mainhand$")] [TomlInlineComment("$ChatBot.AutoFishing.Mainhand$")]
public bool Mainhand = true; public bool Mainhand = true;
[TomlInlineComment("$config.ChatBot.AutoFishing.Auto_Start$")] [TomlInlineComment("$ChatBot.AutoFishing.Auto_Start$")]
public bool Auto_Start = true; public bool Auto_Start = true;
[TomlInlineComment("$config.ChatBot.AutoFishing.Cast_Delay$")] [TomlInlineComment("$ChatBot.AutoFishing.Cast_Delay$")]
public double Cast_Delay = 0.4; public double Cast_Delay = 0.4;
[TomlInlineComment("$config.ChatBot.AutoFishing.Fishing_Delay$")] [TomlInlineComment("$ChatBot.AutoFishing.Fishing_Delay$")]
public double Fishing_Delay = 3.0; public double Fishing_Delay = 3.0;
[TomlInlineComment("$config.ChatBot.AutoFishing.Fishing_Timeout$")] [TomlInlineComment("$ChatBot.AutoFishing.Fishing_Timeout$")]
public double Fishing_Timeout = 300.0; public double Fishing_Timeout = 300.0;
[TomlInlineComment("$config.ChatBot.AutoFishing.Durability_Limit$")] [TomlInlineComment("$ChatBot.AutoFishing.Durability_Limit$")]
public double Durability_Limit = 2; public double Durability_Limit = 2;
[TomlInlineComment("$config.ChatBot.AutoFishing.Auto_Rod_Switch$")] [TomlInlineComment("$ChatBot.AutoFishing.Auto_Rod_Switch$")]
public bool Auto_Rod_Switch = true; public bool Auto_Rod_Switch = true;
[TomlInlineComment("$config.ChatBot.AutoFishing.Stationary_Threshold$")] [TomlInlineComment("$ChatBot.AutoFishing.Stationary_Threshold$")]
public double Stationary_Threshold = 0.001; public double Stationary_Threshold = 0.001;
[TomlInlineComment("$config.ChatBot.AutoFishing.Hook_Threshold$")] [TomlInlineComment("$ChatBot.AutoFishing.Hook_Threshold$")]
public double Hook_Threshold = 0.2; public double Hook_Threshold = 0.2;
[TomlInlineComment("$config.ChatBot.AutoFishing.Log_Fish_Bobber$")] [TomlInlineComment("$ChatBot.AutoFishing.Log_Fish_Bobber$")]
public bool Log_Fish_Bobber = false; public bool Log_Fish_Bobber = false;
[TomlInlineComment("$config.ChatBot.AutoFishing.Enable_Move$")] [TomlInlineComment("$ChatBot.AutoFishing.Enable_Move$")]
public bool Enable_Move = false; public bool Enable_Move = false;
[TomlPrecedingComment("$config.ChatBot.AutoFishing.Movements$")] [TomlPrecedingComment("$ChatBot.AutoFishing.Movements$")]
public LocationConfig[] Movements = new LocationConfig[] public LocationConfig[] Movements = new LocationConfig[]
{ {
new LocationConfig(12.34, -23.45), new LocationConfig(12.34, -23.45),
@ -176,7 +176,7 @@ namespace MinecraftClient.ChatBots
Stopping, Stopping,
} }
public override void Initialize(CommandDispatcher<CmdResult> dispatcher) public override void Initialize()
{ {
if (!GetEntityHandlingEnabled()) if (!GetEntityHandlingEnabled())
{ {
@ -188,7 +188,7 @@ namespace MinecraftClient.ChatBots
if (!inventoryEnabled) if (!inventoryEnabled)
LogToConsole(Translations.bot_autoFish_no_inv_handle); LogToConsole(Translations.bot_autoFish_no_inv_handle);
dispatcher.Register(l => l.Literal("help") Handler.dispatcher.Register(l => l.Literal("help")
.Then(l => l.Literal(CommandName) .Then(l => l.Literal(CommandName)
.Executes(r => OnCommandHelp(r.Source, string.Empty)) .Executes(r => OnCommandHelp(r.Source, string.Empty))
.Then(l => l.Literal("start") .Then(l => l.Literal("start")
@ -202,7 +202,7 @@ namespace MinecraftClient.ChatBots
) )
); );
dispatcher.Register(l => l.Literal(CommandName) Handler.dispatcher.Register(l => l.Literal(CommandName)
.Then(l => l.Literal("start") .Then(l => l.Literal("start")
.Executes(r => OnCommandStart(r.Source))) .Executes(r => OnCommandStart(r.Source)))
.Then(l => l.Literal("stop") .Then(l => l.Literal("stop")
@ -212,14 +212,14 @@ namespace MinecraftClient.ChatBots
.Then(l => l.Literal("clear") .Then(l => l.Literal("clear")
.Executes(r => OnCommandStatusClear(r.Source)))) .Executes(r => OnCommandStatusClear(r.Source))))
.Then(l => l.Literal("_help") .Then(l => l.Literal("_help")
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CommandName))) .Redirect(Handler.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
); );
} }
public override void OnUnload(CommandDispatcher<CmdResult> dispatcher) public override void OnUnload()
{ {
dispatcher.Unregister(CommandName); Handler.dispatcher.Unregister(CommandName);
dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName); Handler.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
} }
private int OnCommandHelp(CmdResult r, string? cmd) private int OnCommandHelp(CmdResult r, string? cmd)
@ -232,7 +232,7 @@ namespace MinecraftClient.ChatBots
"status" => Translations.bot_autoFish_help_status, "status" => Translations.bot_autoFish_help_status,
"help" => Translations.bot_autoFish_help_help, "help" => Translations.bot_autoFish_help_help,
_ => string.Format(Translations.bot_autoFish_available_cmd, "start, stop, status, help") _ => string.Format(Translations.bot_autoFish_available_cmd, "start, stop, status, help")
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false), + '\n' + Handler.dispatcher.GetAllUsageString(CommandName, false),
#pragma warning restore format // @formatter:on #pragma warning restore format // @formatter:on
}); });
} }

View file

@ -21,16 +21,16 @@ namespace MinecraftClient.ChatBots
public bool Enabled = false; public bool Enabled = false;
[TomlInlineComment("$config.ChatBot.AutoRelog.Delay$")] [TomlInlineComment("$ChatBot.AutoRelog.Delay$")]
public Range Delay = new(3); public Range Delay = new(3);
[TomlInlineComment("$config.ChatBot.AutoRelog.Retries$")] [TomlInlineComment("$ChatBot.AutoRelog.Retries$")]
public int Retries = 3; public int Retries = 3;
[TomlInlineComment("$config.ChatBot.AutoRelog.Ignore_Kick_Message$")] [TomlInlineComment("$ChatBot.AutoRelog.Ignore_Kick_Message$")]
public bool Ignore_Kick_Message = false; public bool Ignore_Kick_Message = false;
[TomlPrecedingComment("$config.ChatBot.AutoRelog.Kick_Messages$")] [TomlPrecedingComment("$ChatBot.AutoRelog.Kick_Messages$")]
public string[] Kick_Messages = new string[] { "Connection has been lost", "Server is restarting", "Server is full", "Too Many people" }; public string[] Kick_Messages = new string[] { "Connection has been lost", "Server is restarting", "Server is full", "Too Many people" };
[NonSerialized] [NonSerialized]
@ -85,12 +85,12 @@ namespace MinecraftClient.ChatBots
LogDebugToConsole(string.Format(Translations.bot_autoRelog_launch, Config.Retries)); LogDebugToConsole(string.Format(Translations.bot_autoRelog_launch, Config.Retries));
} }
public override void Initialize(CommandDispatcher<CmdResult> dispatcher) public override void Initialize()
{ {
Initialize(); _Initialize();
} }
private void Initialize() private void _Initialize()
{ {
McClient.ReconnectionAttemptsLeft = Config.Retries; McClient.ReconnectionAttemptsLeft = Config.Retries;
if (Config.Ignore_Kick_Message) if (Config.Ignore_Kick_Message)

View file

@ -30,7 +30,7 @@ namespace MinecraftClient.ChatBots
public string Matches_File = @"matches.ini"; public string Matches_File = @"matches.ini";
[TomlInlineComment("$config.ChatBot.AutoRespond.Match_Colors$")] [TomlInlineComment("$ChatBot.AutoRespond.Match_Colors$")]
public bool Match_Colors = false; public bool Match_Colors = false;
public void OnSettingUpdate() public void OnSettingUpdate()
@ -187,7 +187,7 @@ namespace MinecraftClient.ChatBots
/// <summary> /// <summary>
/// Initialize the AutoRespond bot from the matches file /// Initialize the AutoRespond bot from the matches file
/// </summary> /// </summary>
public override void Initialize(CommandDispatcher<CmdResult> dispatcher) public override void Initialize()
{ {
if (File.Exists(Config.Matches_File)) if (File.Exists(Config.Matches_File))
{ {

View file

@ -44,22 +44,22 @@ namespace MinecraftClient.ChatBots
public bool Enabled = false; public bool Enabled = false;
[TomlInlineComment("$config.ChatBot.DiscordBridge.Token$")] [TomlInlineComment("$ChatBot.DiscordBridge.Token$")]
public string Token = "your bot token here"; public string Token = "your bot token here";
[TomlInlineComment("$config.ChatBot.DiscordBridge.GuildId$")] [TomlInlineComment("$ChatBot.DiscordBridge.GuildId$")]
public ulong GuildId = 1018553894831403028L; public ulong GuildId = 1018553894831403028L;
[TomlInlineComment("$config.ChatBot.DiscordBridge.ChannelId$")] [TomlInlineComment("$ChatBot.DiscordBridge.ChannelId$")]
public ulong ChannelId = 1018565295654326364L; public ulong ChannelId = 1018565295654326364L;
[TomlInlineComment("$config.ChatBot.DiscordBridge.OwnersIds$")] [TomlInlineComment("$ChatBot.DiscordBridge.OwnersIds$")]
public ulong[] OwnersIds = new[] { 978757810781323276UL }; public ulong[] OwnersIds = new[] { 978757810781323276UL };
[TomlInlineComment("$config.ChatBot.DiscordBridge.MessageSendTimeout$")] [TomlInlineComment("$ChatBot.DiscordBridge.MessageSendTimeout$")]
public int Message_Send_Timeout = 3; public int Message_Send_Timeout = 3;
[TomlPrecedingComment("$config.ChatBot.DiscordBridge.Formats$")] [TomlPrecedingComment("$ChatBot.DiscordBridge.Formats$")]
public string PrivateMessageFormat = "**[Private Message]** {username}: {message}"; public string PrivateMessageFormat = "**[Private Message]** {username}: {message}";
public string PublicMessageFormat = "{username}: {message}"; public string PublicMessageFormat = "{username}: {message}";
public string TeleportRequestMessageFormat = "A new Teleport Request from **{username}**!"; public string TeleportRequestMessageFormat = "A new Teleport Request from **{username}**!";
@ -75,15 +75,15 @@ namespace MinecraftClient.ChatBots
instance = this; instance = this;
} }
public override void Initialize(CommandDispatcher<CmdResult> dispatcher) public override void Initialize()
{ {
dispatcher.Register(l => l.Literal("help") Handler.dispatcher.Register(l => l.Literal("help")
.Then(l => l.Literal(CommandName) .Then(l => l.Literal(CommandName)
.Executes(r => OnCommandHelp(r.Source, string.Empty)) .Executes(r => OnCommandHelp(r.Source, string.Empty))
) )
); );
dispatcher.Register(l => l.Literal(CommandName) Handler.dispatcher.Register(l => l.Literal(CommandName)
.Then(l => l.Literal("direction") .Then(l => l.Literal("direction")
.Then(l => l.Literal("both") .Then(l => l.Literal("both")
.Executes(r => OnCommandDirection(r.Source, BridgeDirection.Both))) .Executes(r => OnCommandDirection(r.Source, BridgeDirection.Both)))
@ -93,16 +93,16 @@ namespace MinecraftClient.ChatBots
.Executes(r => OnCommandDirection(r.Source, BridgeDirection.Discord))) .Executes(r => OnCommandDirection(r.Source, BridgeDirection.Discord)))
) )
.Then(l => l.Literal("_help") .Then(l => l.Literal("_help")
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CommandName))) .Redirect(Handler.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
); );
Task.Run(async () => await MainAsync()); Task.Run(async () => await MainAsync());
} }
public override void OnUnload(CommandDispatcher<CmdResult> dispatcher) public override void OnUnload()
{ {
dispatcher.Unregister(CommandName); Handler.dispatcher.Unregister(CommandName);
dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName); Handler.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
Disconnect(); Disconnect();
} }
@ -112,7 +112,7 @@ namespace MinecraftClient.ChatBots
{ {
#pragma warning disable format // @formatter:off #pragma warning disable format // @formatter:off
_ => "dscbridge direction <both|mc|discord>" _ => "dscbridge direction <both|mc|discord>"
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false), + '\n' + Handler.dispatcher.GetAllUsageString(CommandName, false),
#pragma warning restore format // @formatter:on #pragma warning restore format // @formatter:on
}); });
} }

View file

@ -29,7 +29,7 @@ namespace MinecraftClient.ChatBots
public bool Enabled = false; public bool Enabled = false;
[TomlInlineComment("$config.ChatBot.Farmer.Delay_Between_Tasks$")] [TomlInlineComment("$ChatBot.Farmer.Delay_Between_Tasks$")]
public double Delay_Between_Tasks = 1.0; public double Delay_Between_Tasks = 1.0;
public void OnSettingUpdate() public void OnSettingUpdate()
@ -70,7 +70,7 @@ namespace MinecraftClient.ChatBots
private const string commandDescription = "farmer <start <crop type> [radius:<radius = 30>] [unsafe:<true/false>] [teleport:<true/false>] [debug:<true/false>]|stop>"; private const string commandDescription = "farmer <start <crop type> [radius:<radius = 30>] [unsafe:<true/false>] [teleport:<true/false>] [debug:<true/false>]|stop>";
public override void Initialize(CommandDispatcher<CmdResult> dispatcher) public override void Initialize()
{ {
if (GetProtocolVersion() < Protocol18Handler.MC_1_13_Version) if (GetProtocolVersion() < Protocol18Handler.MC_1_13_Version)
{ {
@ -90,13 +90,13 @@ namespace MinecraftClient.ChatBots
return; return;
} }
dispatcher.Register(l => l.Literal("help") Handler.dispatcher.Register(l => l.Literal("help")
.Then(l => l.Literal(CommandName) .Then(l => l.Literal(CommandName)
.Executes(r => OnCommandHelp(r.Source, string.Empty)) .Executes(r => OnCommandHelp(r.Source, string.Empty))
) )
); );
dispatcher.Register(l => l.Literal(CommandName) Handler.dispatcher.Register(l => l.Literal(CommandName)
.Then(l => l.Literal("stop") .Then(l => l.Literal("stop")
.Executes(r => OnCommandStop(r.Source))) .Executes(r => OnCommandStop(r.Source)))
.Then(l => l.Literal("start") .Then(l => l.Literal("start")
@ -105,14 +105,14 @@ namespace MinecraftClient.ChatBots
.Then(l => l.Argument("OtherArgs", Arguments.GreedyString()) .Then(l => l.Argument("OtherArgs", Arguments.GreedyString())
.Executes(r => OnCommandStart(r.Source, MccArguments.GetFarmerCropType(r, "CropType"), Arguments.GetString(r, "OtherArgs")))))) .Executes(r => OnCommandStart(r.Source, MccArguments.GetFarmerCropType(r, "CropType"), Arguments.GetString(r, "OtherArgs"))))))
.Then(l => l.Literal("_help") .Then(l => l.Literal("_help")
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CommandName))) .Redirect(Handler.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
); );
} }
public override void OnUnload(CommandDispatcher<CmdResult> dispatcher) public override void OnUnload()
{ {
dispatcher.Unregister(CommandName); Handler.dispatcher.Unregister(CommandName);
dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName); Handler.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
} }
private int OnCommandHelp(CmdResult r, string? cmd) private int OnCommandHelp(CmdResult r, string? cmd)
@ -121,7 +121,7 @@ namespace MinecraftClient.ChatBots
{ {
#pragma warning disable format // @formatter:off #pragma warning disable format // @formatter:off
_ => Translations.bot_farmer_desc + ": " + commandDescription _ => Translations.bot_farmer_desc + ": " + commandDescription
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false), + '\n' + Handler.dispatcher.GetAllUsageString(CommandName, false),
#pragma warning restore format // @formatter:on #pragma warning restore format // @formatter:on
}); });
} }

View file

@ -24,10 +24,10 @@ namespace MinecraftClient.ChatBots
public bool Enabled = false; public bool Enabled = false;
[TomlInlineComment("$config.ChatBot.FollowPlayer.Update_Limit$")] [TomlInlineComment("$ChatBot.FollowPlayer.Update_Limit$")]
public double Update_Limit = 1.5; public double Update_Limit = 1.5;
[TomlInlineComment("$config.ChatBot.FollowPlayer.Stop_At_Distance$")] [TomlInlineComment("$ChatBot.FollowPlayer.Stop_At_Distance$")]
public double Stop_At_Distance = 3.0; public double Stop_At_Distance = 3.0;
public void OnSettingUpdate() public void OnSettingUpdate()
@ -44,7 +44,7 @@ namespace MinecraftClient.ChatBots
private int _updateCounter = 0; private int _updateCounter = 0;
private bool _unsafeEnabled = false; private bool _unsafeEnabled = false;
public override void Initialize(CommandDispatcher<CmdResult> dispatcher) public override void Initialize()
{ {
if (!GetEntityHandlingEnabled()) if (!GetEntityHandlingEnabled())
{ {
@ -62,13 +62,13 @@ namespace MinecraftClient.ChatBots
return; return;
} }
dispatcher.Register(l => l.Literal("help") Handler.dispatcher.Register(l => l.Literal("help")
.Then(l => l.Literal(CommandName) .Then(l => l.Literal(CommandName)
.Executes(r => OnCommandHelp(r.Source, string.Empty)) .Executes(r => OnCommandHelp(r.Source, string.Empty))
) )
); );
dispatcher.Register(l => l.Literal(CommandName) Handler.dispatcher.Register(l => l.Literal(CommandName)
.Then(l => l.Literal("start") .Then(l => l.Literal("start")
.Then(l => l.Argument("PlayerName", MccArguments.PlayerName()) .Then(l => l.Argument("PlayerName", MccArguments.PlayerName())
.Executes(r => OnCommandStart(r.Source, Arguments.GetString(r, "PlayerName"), takeRisk: false)) .Executes(r => OnCommandStart(r.Source, Arguments.GetString(r, "PlayerName"), takeRisk: false))
@ -77,14 +77,14 @@ namespace MinecraftClient.ChatBots
.Then(l => l.Literal("stop") .Then(l => l.Literal("stop")
.Executes(r => OnCommandStop(r.Source))) .Executes(r => OnCommandStop(r.Source)))
.Then(l => l.Literal("_help") .Then(l => l.Literal("_help")
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CommandName))) .Redirect(Handler.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
); );
} }
public override void OnUnload(CommandDispatcher<CmdResult> dispatcher) public override void OnUnload()
{ {
dispatcher.Unregister(CommandName); Handler.dispatcher.Unregister(CommandName);
dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName); Handler.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
} }
private int OnCommandHelp(CmdResult r, string? cmd) private int OnCommandHelp(CmdResult r, string? cmd)
@ -93,7 +93,7 @@ namespace MinecraftClient.ChatBots
{ {
#pragma warning disable format // @formatter:off #pragma warning disable format // @formatter:off
_ => Translations.cmd_follow_desc + ": " + Translations.cmd_follow_usage _ => Translations.cmd_follow_desc + ": " + Translations.cmd_follow_usage
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false), + '\n' + Handler.dispatcher.GetAllUsageString(CommandName, false),
#pragma warning restore format // @formatter:on #pragma warning restore format // @formatter:on
}); });
} }

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.IO; using System.IO;
@ -223,7 +223,7 @@ namespace MinecraftClient.ChatBots
/// <summary> /// <summary>
/// Initialization of the Mailer bot /// Initialization of the Mailer bot
/// </summary> /// </summary>
public override void Initialize(CommandDispatcher<CmdResult> dispatcher) public override void Initialize()
{ {
LogDebugToConsole(Translations.bot_mailer_init); LogDebugToConsole(Translations.bot_mailer_init);
LogDebugToConsole(Translations.bot_mailer_init_db + Config.DatabaseFile); LogDebugToConsole(Translations.bot_mailer_init_db + Config.DatabaseFile);
@ -258,53 +258,31 @@ namespace MinecraftClient.ChatBots
mailDbFileMonitor = new FileMonitor(Path.GetDirectoryName(Config.DatabaseFile)!, Path.GetFileName(Config.DatabaseFile), FileMonitorCallback); mailDbFileMonitor = new FileMonitor(Path.GetDirectoryName(Config.DatabaseFile)!, Path.GetFileName(Config.DatabaseFile), FileMonitorCallback);
ignoreListFileMonitor = new FileMonitor(Path.GetDirectoryName(Config.IgnoreListFile)!, Path.GetFileName(Config.IgnoreListFile), FileMonitorCallback); ignoreListFileMonitor = new FileMonitor(Path.GetDirectoryName(Config.IgnoreListFile)!, Path.GetFileName(Config.IgnoreListFile), FileMonitorCallback);
dispatcher.Register(l => Handler.dispatcher.Register(l => l.Literal("help")
l.Literal("help") .Then(l => l.Literal(CommandName)
.Then(l => l.Literal(CommandName) .Executes(r => OnCommandHelp(string.Empty)))
.Executes(r => OnCommandHelp(string.Empty))
.Then(l => l.Argument("any", Arguments.GreedyString()).Executes(r => OnCommandHelp(string.Empty)))
)
); );
dispatcher.Register(l => Handler.dispatcher.Register(l => l.Literal(CommandName)
l.Literal(CommandName) .Then(l => l.Literal("getmails")
.Executes(r => OnCommandHelp(string.Empty)) .Executes(r => OnCommandGetMails()))
.Then(l => l.Literal("getmails") .Then(l => l.Literal("getignored")
.Executes(r => OnCommandGetMails()) .Executes(r => OnCommandGetIgnored()))
.Then(l => l.Argument("any", Arguments.GreedyString()).Executes(r => OnCommandHelp("getmails"))) .Then(l => l.Literal("addignored")
) .Then(l => l.Argument("username", Arguments.String())
.Then(l => l.Literal("getignored") .Executes(r => OnCommandAddIgnored(Arguments.GetString(r, "username")))))
.Executes(r => OnCommandGetIgnored()) .Then(l => l.Literal("removeignored")
.Then(l => l.Argument("any", Arguments.GreedyString()).Executes(r => OnCommandHelp("getignored"))) .Then(l => l.Argument("username", Arguments.String())
) .Executes(r => OnCommandRemoveIgnored(Arguments.GetString(r, "username")))))
.Then(l => l.Literal("addignored") .Then(l => l.Literal("_help")
.Executes(r => OnCommandHelp("addignored")) .Redirect(Handler.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
.Then(l => l.Argument("username", Arguments.String())
.Executes(r => OnCommandAddIgnored(Arguments.GetString(r, "username")))
.Then(l => l.Argument("any", Arguments.GreedyString()).Executes(r => OnCommandHelp("addignored")))
)
.Then(l => l.Argument("any", Arguments.GreedyString()).Executes(r => OnCommandHelp("addignored")))
)
.Then(l => l.Literal("removeignored")
.Executes(r => OnCommandHelp("removeignored"))
.Then(l => l.Argument("username", Arguments.String())
.Executes(r => OnCommandRemoveIgnored(Arguments.GetString(r, "username")))
.Then(l => l.Argument("any", Arguments.GreedyString()).Executes(r => OnCommandHelp("removeignored")))
)
.Then(l => l.Argument("any", Arguments.GreedyString()).Executes(r => OnCommandHelp("removeignored")))
)
.Then(l => l.Literal("_help")
.Executes(r => OnCommandHelp(string.Empty))
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CommandName))
)
.Then(l => l.Argument("any", Arguments.GreedyString()).Executes(r => OnCommandHelp(string.Empty)))
); );
} }
public override void OnUnload(CommandDispatcher<CmdResult> dispatcher) public override void OnUnload()
{ {
dispatcher.Unregister(CommandName); Handler.dispatcher.Unregister(CommandName);
dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName); Handler.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
} }
private int OnCommandHelp(string cmd) private int OnCommandHelp(string cmd)
@ -313,7 +291,7 @@ namespace MinecraftClient.ChatBots
{ {
#pragma warning disable format // @formatter:off #pragma warning disable format // @formatter:off
_ => Translations.bot_mailer_cmd_help + ": /mailer <getmails|addignored|getignored|removeignored>" _ => Translations.bot_mailer_cmd_help + ": /mailer <getmails|addignored|getignored|removeignored>"
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false), + '\n' + Handler.dispatcher.GetAllUsageString(CommandName, false),
#pragma warning restore format // @formatter:on #pragma warning restore format // @formatter:on
}); });
return 1; return 1;

View file

@ -35,28 +35,28 @@ namespace MinecraftClient.ChatBots
public bool Enabled = false; public bool Enabled = false;
[TomlInlineComment("$config.ChatBot.Map.Render_In_Console$")] [TomlInlineComment("$ChatBot.Map.Render_In_Console$")]
public bool Render_In_Console = true; public bool Render_In_Console = true;
[TomlInlineComment("$config.ChatBot.Map.Save_To_File$")] [TomlInlineComment("$ChatBot.Map.Save_To_File$")]
public bool Save_To_File = false; public bool Save_To_File = false;
[TomlInlineComment("$config.ChatBot.Map.Auto_Render_On_Update$")] [TomlInlineComment("$ChatBot.Map.Auto_Render_On_Update$")]
public bool Auto_Render_On_Update = false; public bool Auto_Render_On_Update = false;
[TomlInlineComment("$config.ChatBot.Map.Delete_All_On_Unload$")] [TomlInlineComment("$ChatBot.Map.Delete_All_On_Unload$")]
public bool Delete_All_On_Unload = true; public bool Delete_All_On_Unload = true;
[TomlInlineComment("$config.ChatBot.Map.Notify_On_First_Update$")] [TomlInlineComment("$ChatBot.Map.Notify_On_First_Update$")]
public bool Notify_On_First_Update = true; public bool Notify_On_First_Update = true;
[TomlInlineComment("$config.ChatBot.Map.Rasize_Rendered_Image$")] [TomlInlineComment("$ChatBot.Map.Rasize_Rendered_Image$")]
public bool Rasize_Rendered_Image = false; public bool Rasize_Rendered_Image = false;
[TomlInlineComment("$config.ChatBot.Map.Resize_To$")] [TomlInlineComment("$ChatBot.Map.Resize_To$")]
public int Resize_To = 512; public int Resize_To = 512;
[TomlPrecedingComment("$config.ChatBot.Map.Send_Rendered_To_Bridges$")] [TomlPrecedingComment("$ChatBot.Map.Send_Rendered_To_Bridges$")]
public bool Send_Rendered_To_Discord = false; public bool Send_Rendered_To_Discord = false;
public bool Send_Rendered_To_Telegram = false; public bool Send_Rendered_To_Telegram = false;
@ -73,20 +73,20 @@ namespace MinecraftClient.ChatBots
private readonly Queue<QueuedMap> discordQueue = new(); private readonly Queue<QueuedMap> discordQueue = new();
public override void Initialize(CommandDispatcher<CmdResult> dispatcher) public override void Initialize()
{ {
if (!Directory.Exists(baseDirectory)) if (!Directory.Exists(baseDirectory))
Directory.CreateDirectory(baseDirectory); Directory.CreateDirectory(baseDirectory);
DeleteRenderedMaps(); DeleteRenderedMaps();
dispatcher.Register(l => l.Literal("help") Handler.dispatcher.Register(l => l.Literal("help")
.Then(l => l.Literal(CommandName) .Then(l => l.Literal(CommandName)
.Executes(r => OnCommandHelp(r.Source, string.Empty)) .Executes(r => OnCommandHelp(r.Source, string.Empty))
) )
); );
dispatcher.Register(l => l.Literal(CommandName) Handler.dispatcher.Register(l => l.Literal(CommandName)
.Executes(r => OnCommandList(r.Source)) .Executes(r => OnCommandList(r.Source))
.Then(l => l.Literal("list") .Then(l => l.Literal("list")
.Executes(r => OnCommandList(r.Source))) .Executes(r => OnCommandList(r.Source)))
@ -94,14 +94,14 @@ namespace MinecraftClient.ChatBots
.Then(l => l.Argument("MapID", MccArguments.MapBotMapId()) .Then(l => l.Argument("MapID", MccArguments.MapBotMapId())
.Executes(r => OnCommandRender(r.Source, Arguments.GetInteger(r, "MapID"))))) .Executes(r => OnCommandRender(r.Source, Arguments.GetInteger(r, "MapID")))))
.Then(l => l.Literal("_help") .Then(l => l.Literal("_help")
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CommandName))) .Redirect(Handler.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
); );
} }
public override void OnUnload(CommandDispatcher<CmdResult> dispatcher) public override void OnUnload()
{ {
dispatcher.Unregister(CommandName); Handler.dispatcher.Unregister(CommandName);
dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName); Handler.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
DeleteRenderedMaps(); DeleteRenderedMaps();
} }
@ -111,7 +111,7 @@ namespace MinecraftClient.ChatBots
{ {
#pragma warning disable format // @formatter:off #pragma warning disable format // @formatter:off
_ => Translations.error_usage + ": /maps <list/render <id>>" _ => Translations.error_usage + ": /maps <list/render <id>>"
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false), + '\n' + Handler.dispatcher.GetAllUsageString(CommandName, false),
#pragma warning restore format // @formatter:on #pragma warning restore format // @formatter:on
}); });
} }

View file

@ -23,7 +23,7 @@ namespace MinecraftClient.ChatBots
public string File = "playerlog.txt"; public string File = "playerlog.txt";
[TomlInlineComment("$config.ChatBot.PlayerListLogger.Delay$")] [TomlInlineComment("$ChatBot.PlayerListLogger.Delay$")]
public double Delay = 60; public double Delay = 60;
public void OnSettingUpdate() public void OnSettingUpdate()

View file

@ -27,7 +27,7 @@ namespace MinecraftClient.ChatBots
public bool Enabled = false; public bool Enabled = false;
[TomlInlineComment("$config.ChatBot.ReplayCapture.Backup_Interval$")] [TomlInlineComment("$ChatBot.ReplayCapture.Backup_Interval$")]
public double Backup_Interval = 300.0; public double Backup_Interval = 300.0;
public void OnSettingUpdate() public void OnSettingUpdate()
@ -40,33 +40,33 @@ namespace MinecraftClient.ChatBots
private ReplayHandler? replay; private ReplayHandler? replay;
private int backupCounter = -1; private int backupCounter = -1;
public override void Initialize(CommandDispatcher<CmdResult> dispatcher) public override void Initialize()
{ {
SetNetworkPacketEventEnabled(true); SetNetworkPacketEventEnabled(true);
replay = new ReplayHandler(GetProtocolVersion()); replay = new ReplayHandler(GetProtocolVersion());
replay.MetaData.serverName = GetServerHost() + GetServerPort(); replay.MetaData.serverName = GetServerHost() + GetServerPort();
backupCounter = Settings.DoubleToTick(Config.Backup_Interval); backupCounter = Settings.DoubleToTick(Config.Backup_Interval);
dispatcher.Register(l => l.Literal("help") Handler.dispatcher.Register(l => l.Literal("help")
.Then(l => l.Literal(CommandName) .Then(l => l.Literal(CommandName)
.Executes(r => OnCommandHelp(r.Source, string.Empty)) .Executes(r => OnCommandHelp(r.Source, string.Empty))
) )
); );
dispatcher.Register(l => l.Literal(CommandName) Handler.dispatcher.Register(l => l.Literal(CommandName)
.Then(l => l.Literal("save") .Then(l => l.Literal("save")
.Executes(r => OnCommandSave(r.Source))) .Executes(r => OnCommandSave(r.Source)))
.Then(l => l.Literal("stop") .Then(l => l.Literal("stop")
.Executes(r => OnCommandStop(r.Source))) .Executes(r => OnCommandStop(r.Source)))
.Then(l => l.Literal("_help") .Then(l => l.Literal("_help")
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CommandName))) .Redirect(Handler.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
); );
} }
public override void OnUnload(CommandDispatcher<CmdResult> dispatcher) public override void OnUnload()
{ {
dispatcher.Unregister(CommandName); Handler.dispatcher.Unregister(CommandName);
dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName); Handler.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
} }
private int OnCommandHelp(CmdResult r, string? cmd) private int OnCommandHelp(CmdResult r, string? cmd)
@ -75,7 +75,7 @@ namespace MinecraftClient.ChatBots
{ {
#pragma warning disable format // @formatter:off #pragma warning disable format // @formatter:off
_ => string.Format(Translations.general_available_cmd, "save, stop") _ => string.Format(Translations.general_available_cmd, "save, stop")
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false), + '\n' + Handler.dispatcher.GetAllUsageString(CommandName, false),
#pragma warning restore format // @formatter:on #pragma warning restore format // @formatter:on
}); });
} }

View file

@ -127,7 +127,7 @@ namespace MinecraftClient.ChatBots
return false; return false;
} }
public override void Initialize(CommandDispatcher<CmdResult> dispatcher) public override void Initialize()
{ {
//Load the given file from the startup parameters //Load the given file from the startup parameters
if (LookForScript(ref file!)) if (LookForScript(ref file!))

View file

@ -47,19 +47,19 @@ namespace MinecraftClient.ChatBots
public bool Enabled = false; public bool Enabled = false;
[TomlInlineComment("$config.ChatBot.TelegramBridge.Token$")] [TomlInlineComment("$ChatBot.TelegramBridge.Token$")]
public string Token = "your bot token here"; public string Token = "your bot token here";
[TomlInlineComment("$config.ChatBot.TelegramBridge.ChannelId$")] [TomlInlineComment("$ChatBot.TelegramBridge.ChannelId$")]
public string ChannelId = ""; public string ChannelId = "";
[TomlInlineComment("$config.ChatBot.TelegramBridge.Authorized_Chat_Ids$")] [TomlInlineComment("$ChatBot.TelegramBridge.Authorized_Chat_Ids$")]
public long[] Authorized_Chat_Ids = Array.Empty<long>(); public long[] Authorized_Chat_Ids = Array.Empty<long>();
[TomlInlineComment("$config.ChatBot.TelegramBridge.MessageSendTimeout$")] [TomlInlineComment("$ChatBot.TelegramBridge.MessageSendTimeout$")]
public int Message_Send_Timeout = 3; public int Message_Send_Timeout = 3;
[TomlPrecedingComment("$config.ChatBot.TelegramBridge.Formats$")] [TomlPrecedingComment("$ChatBot.TelegramBridge.Formats$")]
public string PrivateMessageFormat = "*(Private Message)* {username}: {message}"; public string PrivateMessageFormat = "*(Private Message)* {username}: {message}";
public string PublicMessageFormat = "{username}: {message}"; public string PublicMessageFormat = "{username}: {message}";
public string TeleportRequestMessageFormat = "A new Teleport Request from **{username}**!"; public string TeleportRequestMessageFormat = "A new Teleport Request from **{username}**!";
@ -75,15 +75,15 @@ namespace MinecraftClient.ChatBots
instance = this; instance = this;
} }
public override void Initialize(CommandDispatcher<CmdResult> dispatcher) public override void Initialize()
{ {
dispatcher.Register(l => l.Literal("help") Handler.dispatcher.Register(l => l.Literal("help")
.Then(l => l.Literal(CommandName) .Then(l => l.Literal(CommandName)
.Executes(r => OnCommandHelp(r.Source, string.Empty)) .Executes(r => OnCommandHelp(r.Source, string.Empty))
) )
); );
dispatcher.Register(l => l.Literal(CommandName) Handler.dispatcher.Register(l => l.Literal(CommandName)
.Then(l => l.Literal("direction") .Then(l => l.Literal("direction")
.Then(l => l.Literal("both") .Then(l => l.Literal("both")
.Executes(r => OnCommandDirection(r.Source, BridgeDirection.Both))) .Executes(r => OnCommandDirection(r.Source, BridgeDirection.Both)))
@ -92,16 +92,16 @@ namespace MinecraftClient.ChatBots
.Then(l => l.Literal("telegram") .Then(l => l.Literal("telegram")
.Executes(r => OnCommandDirection(r.Source, BridgeDirection.Telegram)))) .Executes(r => OnCommandDirection(r.Source, BridgeDirection.Telegram))))
.Then(l => l.Literal("_help") .Then(l => l.Literal("_help")
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CommandName))) .Redirect(Handler.dispatcher.GetRoot().GetChild("help").GetChild(CommandName)))
); );
Task.Run(async () => await MainAsync()); Task.Run(async () => await MainAsync());
} }
public override void OnUnload(CommandDispatcher<CmdResult> dispatcher) public override void OnUnload()
{ {
dispatcher.Unregister(CommandName); Handler.dispatcher.Unregister(CommandName);
dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName); Handler.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName);
Disconnect(); Disconnect();
} }
@ -111,7 +111,7 @@ namespace MinecraftClient.ChatBots
{ {
#pragma warning disable format // @formatter:off #pragma warning disable format // @formatter:off
_ => Translations.error_usage + ": /tgbridge direction <both|mc|telegram>" _ => Translations.error_usage + ": /tgbridge direction <both|mc|telegram>"
+ '\n' + McClient.dispatcher.GetAllUsageString(CommandName, false), + '\n' + Handler.dispatcher.GetAllUsageString(CommandName, false),
#pragma warning restore format // @formatter:on #pragma warning restore format // @formatter:on
}); });
} }

View file

@ -36,7 +36,7 @@ namespace MinecraftClient
StringBuilder sb = new(); StringBuilder sb = new();
string s = (string.IsNullOrEmpty(CmdUsage) || string.IsNullOrEmpty(CmdDesc)) ? string.Empty : ": "; // If either one is empty, no colon : string s = (string.IsNullOrEmpty(CmdUsage) || string.IsNullOrEmpty(CmdDesc)) ? string.Empty : ": "; // If either one is empty, no colon :
sb.Append("§e").Append(cmdChar).Append(CmdUsage).Append("§r").Append(s).AppendLine(CmdDesc); sb.Append("§e").Append(cmdChar).Append(CmdUsage).Append("§r").Append(s).AppendLine(CmdDesc);
sb.Append(McClient.dispatcher.GetAllUsageString(CmdName, false)); sb.Append(CmdResult.client!.dispatcher.GetAllUsageString(CmdName, false));
return sb.ToString(); return sb.ToString();
} }

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Text; using System.Text;
using Brigadier.NET; using Brigadier.NET;
using Brigadier.NET.Builder; using Brigadier.NET.Builder;

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Text; using System.Text;

View file

@ -1,4 +1,4 @@
using Brigadier.NET; using Brigadier.NET;
using Brigadier.NET.Builder; using Brigadier.NET.Builder;
using MinecraftClient.CommandHandler; using MinecraftClient.CommandHandler;

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;

View file

@ -1,4 +1,4 @@
using System; using System;
using Brigadier.NET; using Brigadier.NET;
using Brigadier.NET.Builder; using Brigadier.NET.Builder;
using MinecraftClient.CommandHandler; using MinecraftClient.CommandHandler;

View file

@ -1,4 +1,4 @@
using System; using System;
using Brigadier.NET; using Brigadier.NET;
using Brigadier.NET.Builder; using Brigadier.NET.Builder;
using MinecraftClient.CommandHandler; using MinecraftClient.CommandHandler;

View file

@ -1,4 +1,4 @@
using Brigadier.NET; using Brigadier.NET;
using Brigadier.NET.Builder; using Brigadier.NET.Builder;
using MinecraftClient.CommandHandler; using MinecraftClient.CommandHandler;

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Brigadier.NET; using Brigadier.NET;
using Brigadier.NET.Builder; using Brigadier.NET.Builder;

View file

@ -0,0 +1,75 @@
using System.Collections.Generic;
using Brigadier.NET;
using Brigadier.NET.Builder;
using MinecraftClient.CommandHandler;
namespace MinecraftClient.Commands
{
class Upgrade : Command
{
public override string CmdName { get { return "upgrade"; } }
public override string CmdUsage { get { return "upgrade [-f|check|cancel|download]"; } }
public override string CmdDesc { get { return string.Empty; } }
public override void RegisterCommand(McClient handler, CommandDispatcher<CmdResult> dispatcher) {
dispatcher.Register(l => l.Literal("help")
.Then(l => l.Literal(CmdName)
.Executes(r => GetUsage(r.Source, string.Empty))
.Then(l => l.Literal("cancel")
.Executes(r => GetUsage(r.Source, "cancel")))
.Then(l => l.Literal("check")
.Executes(r => GetUsage(r.Source, "check")))
.Then(l => l.Literal("download")
.Executes(r => GetUsage(r.Source, "download")))
)
);
dispatcher.Register(l => l.Literal(CmdName)
.Executes(r => DownloadUpdate(r.Source, force: false))
.Then(l => l.Literal("-f")
.Executes(r => DownloadUpdate(r.Source, force: true)))
.Then(l => l.Literal("download")
.Executes(r => DownloadUpdate(r.Source, force: false))
.Then(l => l.Literal("-f")
.Executes(r => DownloadUpdate(r.Source, force: true))))
.Then(l => l.Literal("check")
.Executes(r => CheckUpdate(r.Source)))
.Then(l => l.Literal("cancel")
.Executes(r => CancelDownloadUpdate(r.Source)))
.Then(l => l.Literal("_help")
.Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName)))
);
}
private int GetUsage(CmdResult r, string? cmd) {
return r.SetAndReturn(cmd switch {
#pragma warning disable format // @formatter:off
"cancel" => GetCmdDescTranslated(),
"check" => GetCmdDescTranslated(),
"download" => GetCmdDescTranslated(),
_ => GetCmdDescTranslated(),
#pragma warning restore format // @formatter:on
});
}
private static int DownloadUpdate(CmdResult r, bool force)
{
if (UpgradeHelper.DownloadLatestBuild(force))
return r.SetAndReturn(CmdResult.Status.Done, Translations.mcc_update_start);
else
return r.SetAndReturn(CmdResult.Status.Fail, Translations.mcc_update_already_running);
}
private static int CancelDownloadUpdate(CmdResult r)
{
UpgradeHelper.CancelDownloadUpdate();
return r.SetAndReturn(CmdResult.Status.Done, Translations.mcc_update_cancel);
}
private static int CheckUpdate(CmdResult r)
{
UpgradeHelper.CheckUpdate(forceUpdate: true);
return r.SetAndReturn(CmdResult.Status.Done, Translations.mcc_update_start);
}
}
}

View file

@ -1,4 +1,4 @@
using Brigadier.NET; using Brigadier.NET;
using Brigadier.NET.Builder; using Brigadier.NET.Builder;
using MinecraftClient.CommandHandler; using MinecraftClient.CommandHandler;
using MinecraftClient.Mapping; using MinecraftClient.Mapping;

View file

@ -4,6 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Brigadier.NET;
using FuzzySharp; using FuzzySharp;
using MinecraftClient.CommandHandler; using MinecraftClient.CommandHandler;
using MinecraftClient.Scripting; using MinecraftClient.Scripting;
@ -182,7 +183,6 @@ namespace MinecraftClient
#endregion #endregion
internal static bool AutoCompleteDone = false; internal static bool AutoCompleteDone = false;
internal static string[] AutoCompleteResult = Array.Empty<string>(); internal static string[] AutoCompleteResult = Array.Empty<string>();
@ -220,7 +220,7 @@ namespace MinecraftClient
string command = fullCommand[offset..]; string command = fullCommand[offset..];
if (command.Length == 0) if (command.Length == 0)
{ {
var childs = McClient.dispatcher.GetRoot().Children; var childs = CmdResult.client!.dispatcher.GetRoot().Children;
int index = 0; int index = 0;
var sugList = new ConsoleInteractive.ConsoleSuggestion.Suggestion[childs.Count + Commands.Count + 1]; var sugList = new ConsoleInteractive.ConsoleSuggestion.Suggestion[childs.Count + Commands.Count + 1];
@ -243,9 +243,9 @@ namespace MinecraftClient
} }
else else
{ {
var parse = McClient.dispatcher.Parse(command, CmdResult.Empty); var parse = CmdResult.client!.dispatcher.Parse(command, CmdResult.Empty);
var suggestion = await McClient.dispatcher.GetCompletionSuggestions(parse, buffer.CursorPosition - offset); var suggestion = await CmdResult.client!.dispatcher.GetCompletionSuggestions(parse, buffer.CursorPosition - offset);
int sugLen = suggestion.List.Count; int sugLen = suggestion.List.Count;
if (sugLen == 0) if (sugLen == 0)
@ -324,7 +324,7 @@ namespace MinecraftClient
MergeCommands(); MergeCommands();
} }
public static void InitAutocomplete() public static void InitCommandList(CommandDispatcher<CmdResult> dispatcher)
{ {
autocomplete_engine!.AutoComplete("/"); autocomplete_engine!.AutoComplete("/");
} }

View file

@ -25,7 +25,7 @@ namespace MinecraftClient
if (Settings.Config.Logging.DebugMessages) if (Settings.Config.Logging.DebugMessages)
{ {
string callerClass = new System.Diagnostics.StackFrame(1).GetMethod()!.DeclaringType!.Name; string callerClass = new System.Diagnostics.StackFrame(1).GetMethod()!.DeclaringType!.Name;
ConsoleIO.WriteLineFormatted(string.Format(Translations.filemonitor_init, callerClass, Path.Combine(folder, filename))); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.filemonitor_init, callerClass, Path.Combine(folder, filename)));
} }
try try
@ -43,7 +43,7 @@ namespace MinecraftClient
if (Settings.Config.Logging.DebugMessages) if (Settings.Config.Logging.DebugMessages)
{ {
string callerClass = new System.Diagnostics.StackFrame(1).GetMethod()!.DeclaringType!.Name; string callerClass = new System.Diagnostics.StackFrame(1).GetMethod()!.DeclaringType!.Name;
ConsoleIO.WriteLineFormatted(string.Format(Translations.filemonitor_fail, callerClass)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.filemonitor_fail, callerClass));
} }
monitor = null; monitor = null;

View file

@ -1,4 +1,4 @@
namespace MinecraftClient.Inventory namespace MinecraftClient.Inventory
{ {
/// <summary> /// <summary>
/// Represents a Minecraft effects /// Represents a Minecraft effects

View file

@ -1,4 +1,4 @@
namespace MinecraftClient.Inventory namespace MinecraftClient.Inventory
{ {
/// <summary> /// <summary>
/// Represents a Minecraft hand /// Represents a Minecraft hand

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Inventory.ItemPalettes namespace MinecraftClient.Inventory.ItemPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Inventory.ItemPalettes namespace MinecraftClient.Inventory.ItemPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Inventory.ItemPalettes namespace MinecraftClient.Inventory.ItemPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Inventory.ItemPalettes namespace MinecraftClient.Inventory.ItemPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Inventory.ItemPalettes namespace MinecraftClient.Inventory.ItemPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Inventory.ItemPalettes namespace MinecraftClient.Inventory.ItemPalettes
{ {

View file

@ -1,4 +1,4 @@
namespace MinecraftClient.Inventory namespace MinecraftClient.Inventory
{ {
/// <summary> /// <summary>
/// Generated using the --generator flag on the client /// Generated using the --generator flag on the client

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Mapping.BlockPalettes namespace MinecraftClient.Mapping.BlockPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Mapping.BlockPalettes namespace MinecraftClient.Mapping.BlockPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Mapping.BlockPalettes namespace MinecraftClient.Mapping.BlockPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Mapping.BlockPalettes namespace MinecraftClient.Mapping.BlockPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Mapping.BlockPalettes namespace MinecraftClient.Mapping.BlockPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Mapping.BlockPalettes namespace MinecraftClient.Mapping.BlockPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Mapping.BlockPalettes namespace MinecraftClient.Mapping.BlockPalettes
{ {

View file

@ -1,4 +1,4 @@
namespace MinecraftClient.Mapping namespace MinecraftClient.Mapping
{ {
/// <summary> /// <summary>
/// Represents a unit movement in the world /// Represents a unit movement in the world

View file

@ -1,4 +1,4 @@
namespace MinecraftClient.Mapping namespace MinecraftClient.Mapping
{ {
/// <summary> /// <summary>
/// Represents a unit movement in the world /// Represents a unit movement in the world

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using MinecraftClient.Inventory; using MinecraftClient.Inventory;
using MinecraftClient.Protocol.Message; using MinecraftClient.Protocol.Message;

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityPalettes namespace MinecraftClient.Mapping.EntityPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityPalettes namespace MinecraftClient.Mapping.EntityPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityPalettes namespace MinecraftClient.Mapping.EntityPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityPalettes namespace MinecraftClient.Mapping.EntityPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityPalettes namespace MinecraftClient.Mapping.EntityPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityPalettes namespace MinecraftClient.Mapping.EntityPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityPalettes namespace MinecraftClient.Mapping.EntityPalettes
{ {

View file

@ -1,4 +1,4 @@
namespace MinecraftClient.Mapping namespace MinecraftClient.Mapping
{ {
public enum EntityPose public enum EntityPose
{ {

View file

@ -1,4 +1,4 @@
namespace MinecraftClient.Mapping namespace MinecraftClient.Mapping
{ {
/// <summary> /// <summary>
/// Represents Minecraft Entity Types /// Represents Minecraft Entity Types

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.Sockets; using System.Net.Sockets;
@ -30,7 +30,7 @@ namespace MinecraftClient
{ {
public static int ReconnectionAttemptsLeft = 0; public static int ReconnectionAttemptsLeft = 0;
public static CommandDispatcher<CmdResult> dispatcher = new(); public CommandDispatcher<CmdResult> dispatcher = new();
private readonly Dictionary<Guid, PlayerInfo> onlinePlayers = new(); private readonly Dictionary<Guid, PlayerInfo> onlinePlayers = new();
private static bool commandsLoaded = false; private static bool commandsLoaded = false;
@ -810,7 +810,7 @@ namespace MinecraftClient
b.SetHandler(this); b.SetHandler(this);
bots.Add(b); bots.Add(b);
if (init) if (init)
DispatchBotEvent(bot => bot.Initialize(dispatcher), new ChatBot[] { b }); DispatchBotEvent(bot => bot.Initialize(), new ChatBot[] { b });
if (handler != null) if (handler != null)
DispatchBotEvent(bot => bot.AfterGameJoined(), new ChatBot[] { b }); DispatchBotEvent(bot => bot.AfterGameJoined(), new ChatBot[] { b });
} }
@ -826,7 +826,7 @@ namespace MinecraftClient
return; return;
} }
b.OnUnload(dispatcher); b.OnUnload();
bots.RemoveAll(item => ReferenceEquals(item, b)); bots.RemoveAll(item => ReferenceEquals(item, b));
@ -2398,7 +2398,7 @@ namespace MinecraftClient
DispatchBotEvent(bot => bot.AfterGameJoined()); DispatchBotEvent(bot => bot.AfterGameJoined());
ConsoleIO.InitAutocomplete(); ConsoleIO.InitCommandList(dispatcher);
} }
/// <summary> /// <summary>
@ -2952,7 +2952,7 @@ namespace MinecraftClient
/// Called on Entity Equipment /// Called on Entity Equipment
/// </summary> /// </summary>
/// <param name="entityid"> Entity ID</param> /// <param name="entityid"> Entity ID</param>
/// <param name="slot"> Equipment slot. 0: main hand, 1: off hand, 25: armor slot (2: boots, 3: leggings, 4: chestplate, 5: helmet)</param> /// <param name="slot"> Equipment slot. 0: main hand, 1: off hand, 2-5: armor slot (2: boots, 3: leggings, 4: chestplate, 5: helmet)</param>
/// <param name="item"> Item)</param> /// <param name="item"> Item)</param>
public void OnEntityEquipment(int entityid, int slot, Item? item) public void OnEntityEquipment(int entityid, int slot, Item? item)
{ {

View file

@ -35,6 +35,7 @@
<PackageReference Include="FuzzySharp" Version="2.0.2" /> <PackageReference Include="FuzzySharp" Version="2.0.2" />
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="12.2.1" /> <PackageReference Include="Magick.NET-Q16-AnyCPU" Version="12.2.1" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.4.0" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.4.0" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.9" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" /> <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.Windows.Compatibility" Version="7.0.0" /> <PackageReference Include="Microsoft.Windows.Compatibility" Version="7.0.0" />
<PackageReference Include="Samboy063.Tomlet" Version="5.0.1" /> <PackageReference Include="Samboy063.Tomlet" Version="5.0.1" />
@ -79,6 +80,11 @@
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DependentUpon>AsciiArt.resx</DependentUpon> <DependentUpon>AsciiArt.resx</DependentUpon>
</Compile> </Compile>
<Compile Update="Resources\ConfigComments\ConfigComments.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>ConfigComments.resx</DependentUpon>
</Compile>
<Compile Update="Resources\Translations\Translations.Designer.cs"> <Compile Update="Resources\Translations\Translations.Designer.cs">
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
@ -91,6 +97,11 @@
<LastGenOutput>AsciiArt.Designer.cs</LastGenOutput> <LastGenOutput>AsciiArt.Designer.cs</LastGenOutput>
<CustomToolNamespace>MinecraftClient</CustomToolNamespace> <CustomToolNamespace>MinecraftClient</CustomToolNamespace>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Update="Resources\ConfigComments\ConfigComments.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>ConfigComments.Designer.cs</LastGenOutput>
<CustomToolNamespace>MinecraftClient</CustomToolNamespace>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Translations\Translations.resx"> <EmbeddedResource Update="Resources\Translations\Translations.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Translations.Designer.cs</LastGenOutput> <LastGenOutput>Translations.Designer.cs</LastGenOutput>

View file

@ -3,10 +3,8 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net.Http;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Inventory.ItemPalettes;
@ -140,7 +138,7 @@ namespace MinecraftClient
Config.Main.Advanced.Language = Settings.GetDefaultGameLanguage(); Config.Main.Advanced.Language = Settings.GetDefaultGameLanguage();
WriteBackSettings(false); WriteBackSettings(false);
if (newlyGenerated) if (newlyGenerated)
ConsoleIO.WriteLineFormatted(Translations.mcc_settings_generated); ConsoleIO.WriteLineFormatted("§c" + Translations.mcc_settings_generated);
ConsoleIO.WriteLine(Translations.mcc_run_with_default_settings); ConsoleIO.WriteLine(Translations.mcc_run_with_default_settings);
} }
else if (!loadSucceed) else if (!loadSucceed)
@ -201,6 +199,18 @@ namespace MinecraftClient
return; return;
} }
if (args.Contains("--upgrade"))
{
UpgradeHelper.HandleBlockingUpdate(forceUpgrade: false);
return;
}
if (args.Contains("--force-upgrade"))
{
UpgradeHelper.HandleBlockingUpdate(forceUpgrade: true);
return;
}
if (args.Contains("--generate")) if (args.Contains("--generate"))
{ {
string dataGenerator = ""; string dataGenerator = "";
@ -285,47 +295,7 @@ namespace MinecraftClient
} }
// Check for updates // Check for updates
{ UpgradeHelper.CheckUpdate();
bool needPromptUpdate = true;
if (Settings.CheckUpdate(Config.Head.CurrentVersion, Config.Head.LatestVersion))
{
needPromptUpdate = false;
ConsoleIO.WriteLineFormatted(string.Format(Translations.mcc_has_update, Settings.GithubReleaseUrl));
}
Task.Run(() =>
{
HttpClientHandler httpClientHandler = new() { AllowAutoRedirect = false };
HttpClient httpClient = new(httpClientHandler);
Task<HttpResponseMessage>? httpWebRequest = null;
try
{
httpWebRequest = httpClient.GetAsync(Settings.GithubLatestReleaseUrl, HttpCompletionOption.ResponseHeadersRead);
httpWebRequest.Wait();
HttpResponseMessage res = httpWebRequest.Result;
if (res.Headers.Location != null)
{
Match match = Regex.Match(res.Headers.Location.ToString(), Settings.GithubReleaseUrl + @"/tag/(\d{4})(\d{2})(\d{2})-(\d+)");
if (match.Success && match.Groups.Count == 5)
{
string year = match.Groups[1].Value, month = match.Groups[2].Value, day = match.Groups[3].Value, run = match.Groups[4].Value;
string latestVersion = string.Format("GitHub build {0}, built on {1}-{2}-{3}", run, year, month, day);
if (needPromptUpdate)
if (Settings.CheckUpdate(Config.Head.CurrentVersion, Config.Head.LatestVersion))
ConsoleIO.WriteLineFormatted(string.Format(Translations.mcc_has_update, Settings.GithubReleaseUrl));
if (latestVersion != Config.Head.LatestVersion)
{
Config.Head.LatestVersion = latestVersion;
WriteBackSettings(false);
}
}
}
}
catch (Exception) { }
finally { httpWebRequest?.Dispose(); }
httpClient.Dispose();
httpClientHandler.Dispose();
});
}
// Load command-line arguments // Load command-line arguments
if (args.Length >= 1) if (args.Length >= 1)
@ -382,7 +352,7 @@ namespace MinecraftClient
{ {
bool cacheLoaded = SessionCache.InitializeDiskCache(); bool cacheLoaded = SessionCache.InitializeDiskCache();
if (Config.Logging.DebugMessages) if (Config.Logging.DebugMessages)
ConsoleIO.WriteLineFormatted(cacheLoaded ? Translations.debug_session_cache_ok : Translations.debug_session_cache_fail, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + (cacheLoaded ? Translations.debug_session_cache_ok : Translations.debug_session_cache_fail), acceptnewlines: true);
} }
// Setup exit cleaning code // Setup exit cleaning code
@ -416,7 +386,7 @@ namespace MinecraftClient
/// </summary> /// </summary>
private static void RequestPassword() private static void RequestPassword()
{ {
ConsoleIO.WriteLine(ConsoleIO.BasicIO ? string.Format(Translations.mcc_password_basic_io, InternalConfig.Account.Login) + "\n" : Translations.mcc_password); ConsoleIO.WriteLine(ConsoleIO.BasicIO ? string.Format(Translations.mcc_password_basic_io, InternalConfig.Account.Login) + "\n" : Translations.mcc_password_hidden);
string? password = ConsoleIO.BasicIO ? Console.ReadLine() : ConsoleIO.ReadPassword(); string? password = ConsoleIO.BasicIO ? Console.ReadLine() : ConsoleIO.ReadPassword();
if (string.IsNullOrWhiteSpace(password)) if (string.IsNullOrWhiteSpace(password))
InternalConfig.Account.Password = "-"; InternalConfig.Account.Password = "-";
@ -439,7 +409,7 @@ namespace MinecraftClient
string loginLower = ToLowerIfNeed(InternalConfig.Account.Login); string loginLower = ToLowerIfNeed(InternalConfig.Account.Login);
if (InternalConfig.Account.Password == "-") if (InternalConfig.Account.Password == "-")
{ {
ConsoleIO.WriteLineFormatted(Translations.mcc_offline, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.mcc_offline, acceptnewlines: true);
result = ProtocolHandler.LoginResult.Success; result = ProtocolHandler.LoginResult.Success;
session.PlayerID = "0"; session.PlayerID = "0";
session.PlayerName = InternalConfig.Username; session.PlayerName = InternalConfig.Username;
@ -453,7 +423,7 @@ namespace MinecraftClient
result = ProtocolHandler.GetTokenValidation(session); result = ProtocolHandler.GetTokenValidation(session);
if (result != ProtocolHandler.LoginResult.Success) if (result != ProtocolHandler.LoginResult.Success)
{ {
ConsoleIO.WriteLineFormatted(Translations.mcc_session_invalid, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.mcc_session_invalid, acceptnewlines: true);
// Try to refresh access token // Try to refresh access token
if (!string.IsNullOrWhiteSpace(session.RefreshToken)) if (!string.IsNullOrWhiteSpace(session.RefreshToken))
{ {
@ -473,7 +443,7 @@ namespace MinecraftClient
&& !(Config.Main.General.AccountType == LoginType.microsoft && Config.Main.General.Method == LoginMethod.browser)) && !(Config.Main.General.AccountType == LoginType.microsoft && Config.Main.General.Method == LoginMethod.browser))
RequestPassword(); RequestPassword();
} }
else ConsoleIO.WriteLineFormatted(string.Format(Translations.mcc_session_valid, session.PlayerName)); else ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.mcc_session_valid, session.PlayerName));
} }
if (result != ProtocolHandler.LoginResult.Success) if (result != ProtocolHandler.LoginResult.Success)
@ -564,7 +534,7 @@ namespace MinecraftClient
if (protocolversion != 0) if (protocolversion != 0)
ConsoleIO.WriteLineFormatted(string.Format(Translations.mcc_use_version, InternalConfig.MinecraftVersion, protocolversion)); ConsoleIO.WriteLineFormatted(string.Format(Translations.mcc_use_version, InternalConfig.MinecraftVersion, protocolversion));
else else
ConsoleIO.WriteLineFormatted(string.Format(Translations.mcc_unknown_version, InternalConfig.MinecraftVersion)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.mcc_unknown_version, InternalConfig.MinecraftVersion));
if (useMcVersionOnce) if (useMcVersionOnce)
{ {
@ -598,16 +568,16 @@ namespace MinecraftClient
{ {
bool cacheKeyLoaded = KeysCache.InitializeDiskCache(); bool cacheKeyLoaded = KeysCache.InitializeDiskCache();
if (Config.Logging.DebugMessages) if (Config.Logging.DebugMessages)
ConsoleIO.WriteLineFormatted(cacheKeyLoaded ? Translations.debug_keys_cache_ok : Translations.debug_keys_cache_fail, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + (cacheKeyLoaded ? Translations.debug_keys_cache_ok : Translations.debug_keys_cache_fail), acceptnewlines: true);
} }
if (Config.Main.Advanced.ProfileKeyCache != CacheType.none && KeysCache.Contains(loginLower)) if (Config.Main.Advanced.ProfileKeyCache != CacheType.none && KeysCache.Contains(loginLower))
{ {
playerKeyPair = KeysCache.Get(loginLower); playerKeyPair = KeysCache.Get(loginLower);
if (playerKeyPair.NeedRefresh()) if (playerKeyPair.NeedRefresh())
ConsoleIO.WriteLineFormatted(Translations.mcc_profile_key_invalid, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.mcc_profile_key_invalid, acceptnewlines: true);
else else
ConsoleIO.WriteLineFormatted(string.Format(Translations.mcc_profile_key_valid, session.PlayerName)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.mcc_profile_key_valid, session.PlayerName));
} }
if (playerKeyPair == null || playerKeyPair.NeedRefresh()) if (playerKeyPair == null || playerKeyPair.NeedRefresh())

View file

@ -1,4 +1,4 @@
namespace MinecraftClient.Protocol namespace MinecraftClient.Protocol
{ {
public enum EntityActionType public enum EntityActionType
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{ {

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace MinecraftClient.Protocol.Handlers.PacketPalettes namespace MinecraftClient.Protocol.Handlers.PacketPalettes
{ {

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
@ -42,19 +42,19 @@ namespace MinecraftClient.Protocol.Handlers
if (Handler.GetTerrainEnabled()) if (Handler.GetTerrainEnabled())
{ {
ConsoleIO.WriteLineFormatted(Translations.extra_terrainandmovement_disabled, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§c" + Translations.extra_terrainandmovement_disabled, acceptnewlines: true);
Handler.SetTerrainEnabled(false); Handler.SetTerrainEnabled(false);
} }
if (handler.GetInventoryEnabled()) if (handler.GetInventoryEnabled())
{ {
ConsoleIO.WriteLineFormatted(Translations.extra_inventory_disabled, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§c" + Translations.extra_inventory_disabled, acceptnewlines: true);
handler.SetInventoryEnabled(false); handler.SetInventoryEnabled(false);
} }
if (handler.GetEntityHandlingEnabled()) if (handler.GetEntityHandlingEnabled())
{ {
ConsoleIO.WriteLineFormatted(Translations.extra_entity_disabled, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§c" + Translations.extra_entity_disabled, acceptnewlines: true);
handler.SetEntityHandlingEnabled(false); handler.SetEntityHandlingEnabled(false);
} }
} }
@ -500,15 +500,15 @@ namespace MinecraftClient.Protocol.Handlers
byte[] token = ReadNextByteArray(); byte[] token = ReadNextByteArray();
if (serverID == "-") if (serverID == "-")
ConsoleIO.WriteLineFormatted(Translations.mcc_server_offline, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.mcc_server_offline, acceptnewlines: true);
else if (Settings.Config.Logging.DebugMessages) else if (Settings.Config.Logging.DebugMessages)
ConsoleIO.WriteLineFormatted(string.Format(Translations.mcc_handshake, serverID)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.mcc_handshake, serverID));
return StartEncryption(uuid, username, sessionID, token, serverID, PublicServerkey, session); return StartEncryption(uuid, username, sessionID, token, serverID, PublicServerkey, session);
} }
else else
{ {
ConsoleIO.WriteLineFormatted(Translations.error_invalid_response, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.error_invalid_response, acceptnewlines: true);
return false; return false;
} }
} }
@ -519,7 +519,7 @@ namespace MinecraftClient.Protocol.Handlers
byte[] secretKey = CryptoHandler.ClientAESPrivateKey ?? CryptoHandler.GenerateAESPrivateKey(); byte[] secretKey = CryptoHandler.ClientAESPrivateKey ?? CryptoHandler.GenerateAESPrivateKey();
if (Settings.Config.Logging.DebugMessages) if (Settings.Config.Logging.DebugMessages)
ConsoleIO.WriteLineFormatted(Translations.debug_crypto, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.debug_crypto, acceptnewlines: true);
if (serverIDhash != "-") if (serverIDhash != "-")
{ {
@ -584,7 +584,7 @@ namespace MinecraftClient.Protocol.Handlers
} }
else else
{ {
ConsoleIO.WriteLineFormatted(Translations.error_invalid_encrypt, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.error_invalid_encrypt, acceptnewlines: true);
return false; return false;
} }
} }

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
@ -106,18 +106,18 @@ namespace MinecraftClient.Protocol.Handlers
if (handler.GetTerrainEnabled() && protocolVersion > MC_1_19_2_Version) if (handler.GetTerrainEnabled() && protocolVersion > MC_1_19_2_Version)
{ {
log.Error(Translations.extra_terrainandmovement_disabled); log.Error("§c" + Translations.extra_terrainandmovement_disabled);
handler.SetTerrainEnabled(false); handler.SetTerrainEnabled(false);
} }
if (handler.GetInventoryEnabled() && (protocolVersion < MC_1_10_Version || protocolVersion > MC_1_19_2_Version)) if (handler.GetInventoryEnabled() && (protocolVersion < MC_1_10_Version || protocolVersion > MC_1_19_2_Version))
{ {
log.Error(Translations.extra_inventory_disabled); log.Error("§c" + Translations.extra_inventory_disabled);
handler.SetInventoryEnabled(false); handler.SetInventoryEnabled(false);
} }
if (handler.GetEntityHandlingEnabled() && (protocolVersion < MC_1_10_Version || protocolVersion > MC_1_19_2_Version)) if (handler.GetEntityHandlingEnabled() && (protocolVersion < MC_1_10_Version || protocolVersion > MC_1_19_2_Version))
{ {
log.Error(Translations.extra_entity_disabled); log.Error("§c" + Translations.extra_entity_disabled);
handler.SetEntityHandlingEnabled(false); handler.SetEntityHandlingEnabled(false);
} }
@ -1955,12 +1955,12 @@ namespace MinecraftClient.Protocol.Handlers
} }
else if (packetID == 0x02) //Login successful else if (packetID == 0x02) //Login successful
{ {
log.Info(Translations.mcc_server_offline); log.Info("§8" + Translations.mcc_server_offline);
login_phase = false; login_phase = false;
if (!pForge.CompleteForgeHandshake()) if (!pForge.CompleteForgeHandshake())
{ {
log.Error(Translations.error_forge); log.Error("§8" + Translations.error_forge);
return false; return false;
} }
@ -1980,7 +1980,7 @@ namespace MinecraftClient.Protocol.Handlers
RSACryptoServiceProvider RSAService = CryptoHandler.DecodeRSAPublicKey(serverPublicKey)!; RSACryptoServiceProvider RSAService = CryptoHandler.DecodeRSAPublicKey(serverPublicKey)!;
byte[] secretKey = CryptoHandler.ClientAESPrivateKey ?? CryptoHandler.GenerateAESPrivateKey(); byte[] secretKey = CryptoHandler.ClientAESPrivateKey ?? CryptoHandler.GenerateAESPrivateKey();
log.Debug(Translations.debug_crypto); log.Debug("§8" + Translations.debug_crypto);
if (serverIDhash != "-") if (serverIDhash != "-")
{ {
@ -2049,7 +2049,7 @@ namespace MinecraftClient.Protocol.Handlers
(int packetID, Queue<byte> packetData) = ReadNextPacket(); (int packetID, Queue<byte> packetData) = ReadNextPacket();
if (packetID < 0 || loopPrevention-- < 0) // Failed to read packet or too many iterations (issue #1150) if (packetID < 0 || loopPrevention-- < 0) // Failed to read packet or too many iterations (issue #1150)
{ {
handler.OnConnectionLost(ChatBot.DisconnectReason.ConnectionLost, Translations.error_invalid_encrypt); handler.OnConnectionLost(ChatBot.DisconnectReason.ConnectionLost, "§8" + Translations.error_invalid_encrypt);
return false; return false;
} }
else if (packetID == 0x00) //Login rejected else if (packetID == 0x00) //Login rejected
@ -2085,7 +2085,7 @@ namespace MinecraftClient.Protocol.Handlers
if (!pForge.CompleteForgeHandshake()) if (!pForge.CompleteForgeHandshake())
{ {
log.Error(Translations.error_forge_encrypt); log.Error("§8" + Translations.error_forge_encrypt);
return false; return false;
} }
@ -2207,7 +2207,7 @@ namespace MinecraftClient.Protocol.Handlers
// Check for forge on the server. // Check for forge on the server.
Protocol18Forge.ServerInfoCheckForge(jsonData, ref forgeInfo); Protocol18Forge.ServerInfoCheckForge(jsonData, ref forgeInfo);
ConsoleIO.WriteLineFormatted(string.Format(Translations.mcc_server_protocol, version, protocolVersion + (forgeInfo != null ? Translations.mcc_with_forge : ""))); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.mcc_server_protocol, version, protocolVersion + (forgeInfo != null ? Translations.mcc_with_forge : "")));
return true; return true;
} }

View file

@ -133,7 +133,7 @@ namespace MinecraftClient.Protocol.Handlers
byte fmlProtocolVersion = dataTypes.ReadNextByte(packetData); byte fmlProtocolVersion = dataTypes.ReadNextByte(packetData);
if (Settings.Config.Logging.DebugMessages) if (Settings.Config.Logging.DebugMessages)
ConsoleIO.WriteLineFormatted(string.Format(Translations.forge_version, fmlProtocolVersion)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.forge_version, fmlProtocolVersion));
if (fmlProtocolVersion >= 1) if (fmlProtocolVersion >= 1)
currentDimension = dataTypes.ReadNextInt(packetData); currentDimension = dataTypes.ReadNextInt(packetData);
@ -143,7 +143,7 @@ namespace MinecraftClient.Protocol.Handlers
// Then tell the server that we're running the same mods. // Then tell the server that we're running the same mods.
if (Settings.Config.Logging.DebugMessages) if (Settings.Config.Logging.DebugMessages)
ConsoleIO.WriteLineFormatted(Translations.forge_send_mod, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.forge_send_mod, acceptnewlines: true);
byte[][] mods = new byte[forgeInfo.Mods.Count][]; byte[][] mods = new byte[forgeInfo.Mods.Count][];
for (int i = 0; i < forgeInfo.Mods.Count; i++) for (int i = 0; i < forgeInfo.Mods.Count; i++)
{ {
@ -163,7 +163,7 @@ namespace MinecraftClient.Protocol.Handlers
Thread.Sleep(2000); Thread.Sleep(2000);
if (Settings.Config.Logging.DebugMessages) if (Settings.Config.Logging.DebugMessages)
ConsoleIO.WriteLineFormatted(Translations.forge_accept, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.forge_accept, acceptnewlines: true);
// Tell the server that yes, we are OK with the mods it has // Tell the server that yes, we are OK with the mods it has
// even though we don't actually care what mods it has. // even though we don't actually care what mods it has.
@ -185,7 +185,7 @@ namespace MinecraftClient.Protocol.Handlers
int registrySize = dataTypes.ReadNextVarInt(packetData); int registrySize = dataTypes.ReadNextVarInt(packetData);
if (Settings.Config.Logging.DebugMessages) if (Settings.Config.Logging.DebugMessages)
ConsoleIO.WriteLineFormatted(string.Format(Translations.forge_registry, registrySize)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.forge_registry, registrySize));
fmlHandshakeState = FMLHandshakeClientState.PENDINGCOMPLETE; fmlHandshakeState = FMLHandshakeClientState.PENDINGCOMPLETE;
} }
@ -197,7 +197,7 @@ namespace MinecraftClient.Protocol.Handlers
string registryName = dataTypes.ReadNextString(packetData); string registryName = dataTypes.ReadNextString(packetData);
int registrySize = dataTypes.ReadNextVarInt(packetData); int registrySize = dataTypes.ReadNextVarInt(packetData);
if (Settings.Config.Logging.DebugMessages) if (Settings.Config.Logging.DebugMessages)
ConsoleIO.WriteLineFormatted(string.Format(Translations.forge_registry_2, registryName, registrySize)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.forge_registry_2, registryName, registrySize));
if (!hasNextRegistry) if (!hasNextRegistry)
fmlHandshakeState = FMLHandshakeClientState.PENDINGCOMPLETE; fmlHandshakeState = FMLHandshakeClientState.PENDINGCOMPLETE;
} }
@ -209,7 +209,7 @@ namespace MinecraftClient.Protocol.Handlers
if (discriminator != FMLHandshakeDiscriminator.HandshakeAck) if (discriminator != FMLHandshakeDiscriminator.HandshakeAck)
return false; return false;
if (Settings.Config.Logging.DebugMessages) if (Settings.Config.Logging.DebugMessages)
ConsoleIO.WriteLineFormatted(Translations.forge_accept_registry, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.forge_accept_registry, acceptnewlines: true);
SendForgeHandshakePacket(FMLHandshakeDiscriminator.HandshakeAck, SendForgeHandshakePacket(FMLHandshakeDiscriminator.HandshakeAck,
new byte[] { (byte)FMLHandshakeClientState.PENDINGCOMPLETE }); new byte[] { (byte)FMLHandshakeClientState.PENDINGCOMPLETE });
fmlHandshakeState = FMLHandshakeClientState.COMPLETE; fmlHandshakeState = FMLHandshakeClientState.COMPLETE;
@ -303,7 +303,7 @@ namespace MinecraftClient.Protocol.Handlers
// [1]: Version is usually set to "FML2" for FML stuff and "1" for mods // [1]: Version is usually set to "FML2" for FML stuff and "1" for mods
if (Settings.Config.Logging.DebugMessages) if (Settings.Config.Logging.DebugMessages)
ConsoleIO.WriteLineFormatted(Translations.forge_fml2_mod, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.forge_fml2_mod, acceptnewlines: true);
List<string> mods = new(); List<string> mods = new();
int modCount = dataTypes.ReadNextVarInt(packetData); int modCount = dataTypes.ReadNextVarInt(packetData);
@ -335,7 +335,7 @@ namespace MinecraftClient.Protocol.Handlers
// In MCC, we just want to send a valid response so we'll reply back with data collected from the server. // In MCC, we just want to send a valid response so we'll reply back with data collected from the server.
if (Settings.Config.Logging.DebugMessages) if (Settings.Config.Logging.DebugMessages)
ConsoleIO.WriteLineFormatted(Translations.forge_fml2_mod_send, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.forge_fml2_mod_send, acceptnewlines: true);
// Packet ID 2: Client to Server Mod List // Packet ID 2: Client to Server Mod List
fmlResponsePacket.AddRange(dataTypes.GetVarInt(2)); fmlResponsePacket.AddRange(dataTypes.GetVarInt(2));
@ -373,7 +373,7 @@ namespace MinecraftClient.Protocol.Handlers
if (Settings.Config.Logging.DebugMessages) if (Settings.Config.Logging.DebugMessages)
{ {
string registryName = dataTypes.ReadNextString(packetData); string registryName = dataTypes.ReadNextString(packetData);
ConsoleIO.WriteLineFormatted(string.Format(Translations.forge_fml2_registry, registryName)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.forge_fml2_registry, registryName));
} }
fmlResponsePacket.AddRange(dataTypes.GetVarInt(99)); fmlResponsePacket.AddRange(dataTypes.GetVarInt(99));
@ -392,7 +392,7 @@ namespace MinecraftClient.Protocol.Handlers
if (Settings.Config.Logging.DebugMessages) if (Settings.Config.Logging.DebugMessages)
{ {
string configName = dataTypes.ReadNextString(packetData); string configName = dataTypes.ReadNextString(packetData);
ConsoleIO.WriteLineFormatted(string.Format(Translations.forge_fml2_config, configName)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.forge_fml2_config, configName));
} }
fmlResponsePacket.AddRange(dataTypes.GetVarInt(99)); fmlResponsePacket.AddRange(dataTypes.GetVarInt(99));
@ -401,7 +401,7 @@ namespace MinecraftClient.Protocol.Handlers
default: default:
if (Settings.Config.Logging.DebugMessages) if (Settings.Config.Logging.DebugMessages)
ConsoleIO.WriteLineFormatted(string.Format(Translations.forge_fml2_unknown, packetID)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.forge_fml2_unknown, packetID));
break; break;
} }
@ -417,7 +417,7 @@ namespace MinecraftClient.Protocol.Handlers
} }
else if (Settings.Config.Logging.DebugMessages) else if (Settings.Config.Logging.DebugMessages)
{ {
ConsoleIO.WriteLineFormatted(string.Format(Translations.forge_fml2_unknown_channel, fmlChannel)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.forge_fml2_unknown_channel, fmlChannel));
} }
} }
return false; return false;
@ -506,10 +506,10 @@ namespace MinecraftClient.Protocol.Handlers
forgeInfo = new ForgeInfo(modData, fmlVersion); forgeInfo = new ForgeInfo(modData, fmlVersion);
if (forgeInfo.Mods.Any()) if (forgeInfo.Mods.Any())
{ {
ConsoleIO.WriteLineFormatted(string.Format(Translations.forge_with_mod, forgeInfo.Mods.Count)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.forge_with_mod, forgeInfo.Mods.Count));
if (Settings.Config.Logging.DebugMessages) if (Settings.Config.Logging.DebugMessages)
{ {
ConsoleIO.WriteLineFormatted(Translations.forge_mod_list, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.forge_mod_list, acceptnewlines: true);
foreach (ForgeInfo.ForgeMod mod in forgeInfo.Mods) foreach (ForgeInfo.ForgeMod mod in forgeInfo.Mods)
ConsoleIO.WriteLineFormatted("§8 " + mod.ToString()); ConsoleIO.WriteLineFormatted("§8 " + mod.ToString());
} }
@ -517,7 +517,7 @@ namespace MinecraftClient.Protocol.Handlers
} }
else else
{ {
ConsoleIO.WriteLineFormatted(Translations.forge_no_mod, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.forge_no_mod, acceptnewlines: true);
forgeInfo = null; forgeInfo = null;
} }
} }

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using MinecraftClient.Inventory; using MinecraftClient.Inventory;
using MinecraftClient.Mapping; using MinecraftClient.Mapping;

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using MinecraftClient.Inventory; using MinecraftClient.Inventory;
using MinecraftClient.Logger; using MinecraftClient.Logger;

View file

@ -218,7 +218,7 @@ namespace MinecraftClient.Protocol.Message
//File not found? Try downloading language file from Mojang's servers? //File not found? Try downloading language file from Mojang's servers?
if (!File.Exists(Language_File)) if (!File.Exists(Language_File))
{ {
ConsoleIO.WriteLineFormatted(string.Format(Translations.chat_download, Config.Main.Advanced.Language)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.chat_download, Config.Main.Advanced.Language));
HttpClient httpClient = new(); HttpClient httpClient = new();
try try
{ {
@ -244,11 +244,11 @@ namespace MinecraftClient.Protocol.Message
stringBuilder.Append(entry.Key).Append('=').Append(entry.Value.StringValue.Replace("\n", "\\n").Replace("\r", string.Empty)).Append(Environment.NewLine); stringBuilder.Append(entry.Key).Append('=').Append(entry.Value.StringValue.Replace("\n", "\\n").Replace("\r", string.Empty)).Append(Environment.NewLine);
File.WriteAllText(Language_File, stringBuilder.ToString()); File.WriteAllText(Language_File, stringBuilder.ToString());
ConsoleIO.WriteLineFormatted(string.Format(Translations.chat_done, Language_File)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.chat_done, Language_File));
} }
catch catch
{ {
ConsoleIO.WriteLineFormatted(Translations.chat_fail, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.chat_fail, acceptnewlines: true);
} }
httpClient.Dispose(); httpClient.Dispose();
} }
@ -281,7 +281,7 @@ namespace MinecraftClient.Protocol.Message
} }
else //No external dictionnary found. else //No external dictionnary found.
{ {
ConsoleIO.WriteLineFormatted(string.Format(Translations.chat_not_found, Language_File)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.chat_not_found, Language_File));
} }
} }

View file

@ -163,7 +163,7 @@ namespace MinecraftClient.Protocol.ProfileKey
} }
catch (IOException e) catch (IOException e)
{ {
ConsoleIO.WriteLineFormatted(string.Format(Translations.cache_read_fail_plain_keys, e.Message)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.cache_read_fail_plain_keys, e.Message));
} }
} }
@ -176,7 +176,7 @@ namespace MinecraftClient.Protocol.ProfileKey
private static void SaveToDisk() private static void SaveToDisk()
{ {
if (Config.Logging.DebugMessages) if (Config.Logging.DebugMessages)
ConsoleIO.WriteLineFormatted(Translations.cache_saving_keys, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.cache_saving_keys, acceptnewlines: true);
List<string> KeysCacheLines = new() List<string> KeysCacheLines = new()
{ {
@ -192,7 +192,7 @@ namespace MinecraftClient.Protocol.ProfileKey
} }
catch (IOException e) catch (IOException e)
{ {
ConsoleIO.WriteLineFormatted(string.Format(Translations.cache_save_fail_keys, e.Message)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.cache_save_fail_keys, e.Message));
} }
} }
} }

View file

@ -56,7 +56,7 @@ namespace MinecraftClient.Protocol
.ThenBy(record => Guid.NewGuid()) .ThenBy(record => Guid.NewGuid())
.First(); .First();
string target = result.Target.Value.Trim('.'); string target = result.Target.Value.Trim('.');
ConsoleIO.WriteLineFormatted(string.Format(Translations.mcc_found, target, result.Port, domainVal)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.mcc_found, target, result.Port, domainVal));
domainVal = target; domainVal = target;
portVal = result.Port; portVal = result.Port;
foundService = true; foundService = true;
@ -64,7 +64,7 @@ namespace MinecraftClient.Protocol
} }
catch (Exception e) catch (Exception e)
{ {
ConsoleIO.WriteLineFormatted(string.Format(Translations.mcc_not_found, domainVal, e.GetType().FullName, e.Message)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.mcc_not_found, domainVal, e.GetType().FullName, e.Message));
} }
}, TimeSpan.FromSeconds(Config.Main.Advanced.ResolveSrvRecords == MainConfigHealper.MainConfig.AdvancedConfig.ResolveSrvRecordType.fast ? 10 : 30)); }, TimeSpan.FromSeconds(Config.Main.Advanced.ResolveSrvRecords == MainConfigHealper.MainConfig.AdvancedConfig.ResolveSrvRecordType.fast ? 10 : 30));
} }
@ -96,7 +96,7 @@ namespace MinecraftClient.Protocol
success = true; success = true;
} }
else else
ConsoleIO.WriteLineFormatted(Translations.error_unexpect_response, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.error_unexpect_response, acceptnewlines: true);
} }
catch (Exception e) catch (Exception e)
{ {
@ -105,9 +105,9 @@ namespace MinecraftClient.Protocol
}, TimeSpan.FromSeconds(Config.Main.Advanced.ResolveSrvRecords == MainConfigHealper.MainConfig.AdvancedConfig.ResolveSrvRecordType.fast ? 10 : 30))) }, TimeSpan.FromSeconds(Config.Main.Advanced.ResolveSrvRecords == MainConfigHealper.MainConfig.AdvancedConfig.ResolveSrvRecordType.fast ? 10 : 30)))
{ {
if (protocolversion != 0 && protocolversion != protocolversionTmp) if (protocolversion != 0 && protocolversion != protocolversionTmp)
ConsoleIO.WriteLineFormatted(Translations.error_version_different, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.error_version_different, acceptnewlines: true);
if (protocolversion == 0 && protocolversionTmp <= 1) if (protocolversion == 0 && protocolversionTmp <= 1)
ConsoleIO.WriteLineFormatted(Translations.error_no_version_report, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.error_no_version_report, acceptnewlines: true);
if (protocolversion == 0) if (protocolversion == 0)
protocolversion = protocolversionTmp; protocolversion = protocolversionTmp;
forgeInfo = forgeInfoTmp; forgeInfo = forgeInfoTmp;
@ -115,7 +115,7 @@ namespace MinecraftClient.Protocol
} }
else else
{ {
ConsoleIO.WriteLineFormatted(Translations.error_connection_timeout, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.error_connection_timeout, acceptnewlines: true);
return false; return false;
} }
} }
@ -491,7 +491,7 @@ namespace MinecraftClient.Protocol
} }
else else
{ {
ConsoleIO.WriteLineFormatted(string.Format(Translations.error_http_code, code)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.error_http_code, code));
return LoginResult.OtherError; return LoginResult.OtherError;
} }
} }
@ -694,7 +694,7 @@ namespace MinecraftClient.Protocol
} }
else else
{ {
ConsoleIO.WriteLineFormatted(string.Format(Translations.error_auth, code)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.error_auth, code));
return LoginResult.OtherError; return LoginResult.OtherError;
} }
} }
@ -895,7 +895,7 @@ namespace MinecraftClient.Protocol
try try
{ {
if (Settings.Config.Logging.DebugMessages) if (Settings.Config.Logging.DebugMessages)
ConsoleIO.WriteLineFormatted(string.Format(Translations.debug_request, host)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.debug_request, host));
TcpClient client = ProxyHandler.NewTcpClient(host, 443, true); TcpClient client = ProxyHandler.NewTcpClient(host, 443, true);
SslStream stream = new(client.GetStream()); SslStream stream = new(client.GetStream());

View file

@ -1,12 +1,14 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Linq;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Net.Security; using System.Net.Security;
using System.Net.Sockets; using System.Net.Sockets;
using System.Security.Authentication; using System.Security.Authentication;
using System.Text; using System.Text;
using System.Threading;
using MinecraftClient.Proxy; using MinecraftClient.Proxy;
namespace MinecraftClient.Protocol namespace MinecraftClient.Protocol
@ -16,12 +18,21 @@ namespace MinecraftClient.Protocol
/// </summary> /// </summary>
public class ProxiedWebRequest public class ProxiedWebRequest
{ {
private readonly string httpVersion = "HTTP/1.0"; // Use 1.0 here because 1.1 server may send chunked data public interface ITcpFactory
{
TcpClient CreateTcpClient(string host, int port);
};
private readonly string httpVersion = "HTTP/1.1";
private ITcpFactory? tcpFactory;
private bool isProxied = false; // Send absolute Url in request if true
private readonly Uri uri; private readonly Uri uri;
private string Host { get { return uri.Host; } } private string Host { get { return uri.Host; } }
private int Port { get { return uri.Port; } } private int Port { get { return uri.Port; } }
private string Path { get { return uri.PathAndQuery; } } private string Path { get { return uri.PathAndQuery; } }
private string AbsoluteUrl { get { return uri.AbsoluteUri; } }
private bool IsSecure { get { return uri.Scheme == "https"; } } private bool IsSecure { get { return uri.Scheme == "https"; } }
public NameValueCollection Headers = new(); public NameValueCollection Headers = new();
@ -30,6 +41,12 @@ namespace MinecraftClient.Protocol
public string Accept { get { return Headers.Get("Accept") ?? String.Empty; } set { Headers.Set("Accept", value); } } public string Accept { get { return Headers.Get("Accept") ?? String.Empty; } set { Headers.Set("Accept", value); } }
public string Cookie { set { Headers.Set("Cookie", value); } } public string Cookie { set { Headers.Set("Cookie", value); } }
/// <summary>
/// Set to true to tell the http client proxy is enabled
/// </summary>
public bool IsProxy { get { return isProxied; } set { isProxied = value; } }
public bool Debug { get { return Settings.Config.Logging.DebugMessages; } }
/// <summary> /// <summary>
/// Create a new http request /// Create a new http request
/// </summary> /// </summary>
@ -52,13 +69,34 @@ namespace MinecraftClient.Protocol
SetupBasicHeaders(); SetupBasicHeaders();
} }
/// <summary>
/// Create a new http request with custom tcp client
/// </summary>
/// <param name="tcpFactory">Tcp factory to be used</param>
/// <param name="url">Target URL</param>
public ProxiedWebRequest(ITcpFactory tcpFactory, string url) : this(url)
{
this.tcpFactory = tcpFactory;
}
/// <summary>
/// Create a new http request with custom tcp client and cookies
/// </summary>
/// <param name="tcpFactory">Tcp factory to be used</param>
/// <param name="url">Target URL</param>
/// <param name="cookies">Cookies to use</param>
public ProxiedWebRequest(ITcpFactory tcpFactory, string url, NameValueCollection cookies) : this(url, cookies)
{
this.tcpFactory = tcpFactory;
}
/// <summary> /// <summary>
/// Setup some basic headers /// Setup some basic headers
/// </summary> /// </summary>
private void SetupBasicHeaders() private void SetupBasicHeaders()
{ {
Headers.Add("Host", Host); Headers.Add("Host", Host);
Headers.Add("User-Agent", "MCC/" + Program.Version); Headers.Add("User-Agent", "MCC/1.0");
Headers.Add("Accept", "*/*"); Headers.Add("Accept", "*/*");
Headers.Add("Connection", "close"); Headers.Add("Connection", "close");
} }
@ -96,7 +134,7 @@ namespace MinecraftClient.Protocol
{ {
List<string> requestMessage = new() List<string> requestMessage = new()
{ {
string.Format("{0} {1} {2}", method.ToUpper(), Path, httpVersion) // Request line string.Format("{0} {1} {2}", method.ToUpper(), isProxied ? AbsoluteUrl : Path, httpVersion) // Request line
}; };
foreach (string key in Headers) // Headers foreach (string key in Headers) // Headers
{ {
@ -109,7 +147,7 @@ namespace MinecraftClient.Protocol
requestMessage.Add(body); requestMessage.Add(body);
} }
else requestMessage.Add(""); // <CR><LF> else requestMessage.Add(""); // <CR><LF>
if (Settings.Config.Logging.DebugMessages) if (Debug)
{ {
foreach (string l in requestMessage) foreach (string l in requestMessage)
{ {
@ -117,84 +155,240 @@ namespace MinecraftClient.Protocol
} }
} }
Response response = Response.Empty(); Response response = Response.Empty();
AutoTimeout.Perform(() =>
// FIXME: Use TcpFactory interface to avoid direct usage of the ProxyHandler class
// TcpClient client = tcpFactory.CreateTcpClient(Host, Port);
TcpClient client = ProxyHandler.NewTcpClient(Host, Port, true);
Stream stream;
if (IsSecure)
{ {
TcpClient client = ProxyHandler.NewTcpClient(Host, Port, true); stream = new SslStream(client.GetStream());
Stream stream; ((SslStream)stream).AuthenticateAsClient(Host, null, SslProtocols.Tls12, true); // Enable TLS 1.2. Hotfix for #1774
if (IsSecure) }
{ else
stream = new SslStream(client.GetStream()); {
((SslStream)stream).AuthenticateAsClient(Host, null, SslProtocols.Tls12, true); // Enable TLS 1.2. Hotfix for #1774 stream = client.GetStream();
} }
else string h = string.Join("\r\n", requestMessage.ToArray());
{ byte[] data = Encoding.ASCII.GetBytes(h);
stream = client.GetStream(); stream.Write(data, 0, data.Length);
} stream.Flush();
string h = string.Join("\r\n", requestMessage.ToArray());
byte[] data = Encoding.ASCII.GetBytes(h); // Read response
stream.Write(data, 0, data.Length); int statusCode = ReadHttpStatus(stream);
stream.Flush(); var headers = ReadHeader(stream);
StreamReader sr = new(stream); string? rbody;
string rawResult = sr.ReadToEnd(); if (headers.Get("transfer-encoding") == "chunked")
response = ParseResponse(rawResult); {
try rbody = ReadBodyChunked(stream);
{ }
sr.Close(); else
stream.Close(); {
client.Close(); rbody = ReadBody(stream, int.Parse(headers.Get("content-length") ?? "0"));
} }
catch { } if (headers.Get("set-cookie") != null)
}, {
TimeSpan.FromSeconds(30)); response.Cookies = ParseSetCookie(headers.GetValues("set-cookie") ?? Array.Empty<string>());
}
response.Body = rbody ?? "";
response.StatusCode = statusCode;
response.Headers = headers;
try
{
stream.Close();
client.Close();
}
catch { }
return response; return response;
} }
/// <summary> /// <summary>
/// Parse a raw response string to response object /// Read HTTP response line from a Stream
/// </summary> /// </summary>
/// <param name="raw">raw response string</param> /// <param name="s">Stream to read</param>
/// <returns></returns> /// <returns></returns>
private Response ParseResponse(string raw) /// <exception cref="InvalidDataException">If server return unknown data</exception>
private static int ReadHttpStatus(Stream s)
{ {
int statusCode; var httpHeader = ReadLine(s); // http header line
string responseBody = ""; if (httpHeader.StartsWith("HTTP/1.1") || httpHeader.StartsWith("HTTP/1.0"))
NameValueCollection headers = new();
NameValueCollection cookies = new();
if (raw.StartsWith("HTTP/1.1") || raw.StartsWith("HTTP/1.0"))
{ {
Queue<string> msg = new(raw.Split(new string[] { "\r\n" }, StringSplitOptions.None)); return int.Parse(httpHeader.Split(' ')[1], NumberStyles.Any, CultureInfo.CurrentCulture);
statusCode = int.Parse(msg.Dequeue().Split(' ')[1], NumberStyles.Any, CultureInfo.CurrentCulture);
while (msg.Peek() != "")
{
string[] header = msg.Dequeue().Split(new char[] { ':' }, 2); // Split first ':' only
string key = header[0].ToLower(); // Key is case-insensitive
string value = header[1];
if (key == "set-cookie")
{
string[] cookie = value.Split(';'); // cookie options are ignored
string[] tmp = cookie[0].Split(new char[] { '=' }, 2); // Split first '=' only
string cname = tmp[0].Trim();
string cvalue = tmp[1].Trim();
cookies.Add(cname, cvalue);
}
else
{
headers.Add(key, value.Trim());
}
}
msg.Dequeue();
if (msg.Count > 0)
responseBody = msg.Dequeue();
return new Response(statusCode, responseBody, headers, cookies);
} }
else else
{ {
return new Response(520 /* Web Server Returned an Unknown Error */, "", headers, cookies); throw new InvalidDataException("Unexpect data from server");
} }
} }
/// <summary>
/// Read HTTP headers from a Stream
/// </summary>
/// <param name="s">Stream to read</param>
/// <returns>Headers in lower-case</returns>
private static NameValueCollection ReadHeader(Stream s)
{
var headers = new NameValueCollection();
// Read headers
string header;
do
{
header = ReadLine(s);
if (!String.IsNullOrEmpty(header))
{
var tmp = header.Split(new char[] { ':' }, 2);
var name = tmp[0].ToLower();
var value = tmp[1].Trim();
headers.Add(name, value);
}
}
while (!String.IsNullOrEmpty(header));
return headers;
}
/// <summary>
/// Read HTTP body from a Stream
/// </summary>
/// <param name="s">Stream to read</param>
/// <param name="length">Length of the body (the Content-Length header)</param>
/// <returns>Body or null if length is zero</returns>
private static string? ReadBody(Stream s, int length)
{
if (length > 0)
{
byte[] buffer = new byte[length];
int r = 0;
while (r < length)
{
var read = s.Read(buffer, r, length - r);
r += read;
Thread.Sleep(50);
}
return Encoding.UTF8.GetString(buffer);
}
else
{
return null;
}
}
/// <summary>
/// Read HTTP chunked body from a Stream
/// </summary>
/// <param name="s">Stream to read</param>
/// <returns>Body or empty string if nothing is received</returns>
private static string ReadBodyChunked(Stream s)
{
List<byte> buffer1 = new();
while (true)
{
string l = ReadLine(s);
int size = Int32.Parse(l, NumberStyles.HexNumber);
if (size == 0)
break;
byte[] buffer2 = new byte[size];
int r = 0;
while (r < size)
{
var read = s.Read(buffer2, r, size - r);
r += read;
Thread.Sleep(50);
}
ReadLine(s);
buffer1.AddRange(buffer2);
}
return Encoding.UTF8.GetString(buffer1.ToArray());
}
/// <summary>
/// Parse the Set-Cookie header value into NameValueCollection. Cookie options are ignored
/// </summary>
/// <param name="headerValue">Array of value strings</param>
/// <returns>Parsed cookies</returns>
private static NameValueCollection ParseSetCookie(IEnumerable<string> headerValue)
{
NameValueCollection cookies = new();
foreach (var value in headerValue)
{
string[] cookie = value.Split(';'); // cookie options are ignored
string[] tmp = cookie[0].Split(new char[] { '=' }, 2); // Split first '=' only
string[] options = cookie[1..];
string cname = tmp[0].Trim();
string cvalue = tmp[1].Trim();
// Check expire
bool isExpired = false;
foreach (var option in options)
{
var tmp2 = option.Trim().Split(new char[] { '=' }, 2);
// Check for Expires=<date> and Max-Age=<number>
if (tmp2.Length == 2)
{
var optName = tmp2[0].Trim().ToLower();
var optValue = tmp2[1].Trim();
switch (optName)
{
case "expires":
{
if (DateTime.TryParse(optValue, out var expDate))
{
if (expDate < DateTime.Now)
isExpired = true;
}
break;
}
case "max-age":
{
if (int.TryParse(optValue, out var expInt))
{
if (expInt <= 0)
isExpired = true;
}
break;
}
}
}
if (isExpired)
break;
}
if (!isExpired)
cookies.Add(cname, cvalue);
}
return cookies;
}
/// <summary>
/// Read a line from a Stream
/// </summary>
/// <remarks>
/// Line break by \r\n and they are not included in returned string
/// </remarks>
/// <param name="s">Stream to read</param>
/// <returns>String</returns>
private static string ReadLine(Stream s)
{
List<byte> buffer = new();
byte c;
while (true)
{
int b = s.ReadByte();
if (b == -1)
break;
c = (byte)b;
if (c == '\n')
{
if (buffer.Last() == '\r')
{
buffer.RemoveAt(buffer.Count - 1);
break;
}
}
buffer.Add(c);
}
return Encoding.UTF8.GetString(buffer.ToArray());
}
/// <summary> /// <summary>
/// Get the cookie string representation to use in header /// Get the cookie string representation to use in header
/// </summary> /// </summary>

View file

@ -190,7 +190,7 @@ namespace MinecraftClient.Protocol.Session
} }
catch (IOException ex) catch (IOException ex)
{ {
ConsoleIO.WriteLineFormatted(string.Format(Translations.cache_read_fail, ex.Message)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.cache_read_fail, ex.Message));
} }
catch (SerializationException ex2) catch (SerializationException ex2)
{ {
@ -236,7 +236,7 @@ namespace MinecraftClient.Protocol.Session
} }
catch (IOException e) catch (IOException e)
{ {
ConsoleIO.WriteLineFormatted(string.Format(Translations.cache_read_fail_plain, e.Message)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.cache_read_fail_plain, e.Message));
} }
} }
@ -249,7 +249,7 @@ namespace MinecraftClient.Protocol.Session
private static void SaveToDisk() private static void SaveToDisk()
{ {
if (Config.Logging.DebugMessages) if (Config.Logging.DebugMessages)
ConsoleIO.WriteLineFormatted(Translations.cache_saving, acceptnewlines: true); ConsoleIO.WriteLineFormatted("§8" + Translations.cache_saving, acceptnewlines: true);
List<string> sessionCacheLines = new() List<string> sessionCacheLines = new()
{ {
@ -265,7 +265,7 @@ namespace MinecraftClient.Protocol.Session
} }
catch (IOException e) catch (IOException e)
{ {
ConsoleIO.WriteLineFormatted(string.Format(Translations.cache_save_fail, e.Message)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.cache_save_fail, e.Message));
} }
} }
} }

View file

@ -17,22 +17,25 @@ namespace MinecraftClient.Proxy
[TomlDoNotInlineObject] [TomlDoNotInlineObject]
public class Configs public class Configs
{ {
[TomlInlineComment("$config.Proxy.Enabled_Login$")] [TomlInlineComment("$Proxy.Enabled_Update$")]
public bool Enabled_Update = false;
[TomlInlineComment("$Proxy.Enabled_Login$")]
public bool Enabled_Login = false; public bool Enabled_Login = false;
[TomlInlineComment("$config.Proxy.Enabled_Ingame$")] [TomlInlineComment("$Proxy.Enabled_Ingame$")]
public bool Enabled_Ingame = false; public bool Enabled_Ingame = false;
[TomlInlineComment("$config.Proxy.Server$")] [TomlInlineComment("$Proxy.Server$")]
public ProxyInfoConfig Server = new("0.0.0.0", 8080); public ProxyInfoConfig Server = new("0.0.0.0", 8080);
[TomlInlineComment("$config.Proxy.Proxy_Type$")] [TomlInlineComment("$Proxy.Proxy_Type$")]
public ProxyType Proxy_Type = ProxyType.HTTP; public ProxyType Proxy_Type = ProxyType.HTTP;
[TomlInlineComment("$config.Proxy.Username$")] [TomlInlineComment("$Proxy.Username$")]
public string Username = ""; public string Username = "";
[TomlInlineComment("$config.Proxy.Password$")] [TomlInlineComment("$Proxy.Password$")]
public string Password = ""; public string Password = "";
public void OnSettingUpdate() { } public void OnSettingUpdate() { }
@ -79,14 +82,14 @@ namespace MinecraftClient.Proxy
case Configs.ProxyType.SOCKS5: innerProxytype = ProxyType.Socks5; break; case Configs.ProxyType.SOCKS5: innerProxytype = ProxyType.Socks5; break;
} }
if (Config.Username != "" && Config.Password != "") if (!string.IsNullOrWhiteSpace(Config.Username)&& !string.IsNullOrWhiteSpace(Config.Password))
proxy = factory.CreateProxyClient(innerProxytype, Config.Server.Host, Config.Server.Port, Config.Username, Config.Password); proxy = factory.CreateProxyClient(innerProxytype, Config.Server.Host, Config.Server.Port, Config.Username, Config.Password);
else else
proxy = factory.CreateProxyClient(innerProxytype, Config.Server.Host, Config.Server.Port); proxy = factory.CreateProxyClient(innerProxytype, Config.Server.Host, Config.Server.Port);
if (!proxy_ok) if (!proxy_ok)
{ {
ConsoleIO.WriteLineFormatted(string.Format(Translations.proxy_connected, Config.Server.Host, Config.Server.Port)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.proxy_connected, Config.Server.Host, Config.Server.Port));
proxy_ok = true; proxy_ok = true;
} }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,791 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AppVars.Variables" xml:space="preserve">
<value>can be used in some other fields as %yourvar%
%username% and %serverip% are reserved variables.</value>
</data>
<data name="ChatBot" xml:space="preserve">
<value>=============================== #
Minecraft Console Client Bots #
=============================== #</value>
</data>
<data name="ChatBot.Alerts" xml:space="preserve">
<value>Get alerted when specified words are detected in chat
Useful for moderating your server or detecting when someone is talking to you</value>
</data>
<data name="ChatBot.Alerts.Beep_Enabled" xml:space="preserve">
<value>Play a beep sound when a word is detected in addition to highlighting.</value>
</data>
<data name="ChatBot.Alerts.Excludes" xml:space="preserve">
<value>List of words/strings to NOT alert you on.</value>
</data>
<data name="ChatBot.Alerts.Log_File" xml:space="preserve">
<value>The name of a file where alers logs will be written.</value>
</data>
<data name="ChatBot.Alerts.Log_To_File" xml:space="preserve">
<value>Log alerts info a file.</value>
</data>
<data name="ChatBot.Alerts.Matches" xml:space="preserve">
<value>List of words/strings to alert you on.</value>
</data>
<data name="ChatBot.Alerts.Trigger_By_Rain" xml:space="preserve">
<value>Trigger alerts when it rains and when it stops.</value>
</data>
<data name="ChatBot.Alerts.Trigger_By_Thunderstorm" xml:space="preserve">
<value>Triggers alerts at the beginning and end of thunderstorms.</value>
</data>
<data name="ChatBot.Alerts.Trigger_By_Words" xml:space="preserve">
<value>Triggers an alert after receiving a specified keyword.</value>
</data>
<data name="ChatBot.AntiAfk" xml:space="preserve">
<value>Send a command on a regular or random basis or make the bot walk around randomly to avoid automatic AFK disconnection
/!\ Make sure your server rules do not forbid anti-AFK mechanisms!
/!\ Make sure you keep the bot in an enclosure to prevent it wandering off if you're using terrain handling! (Recommended size 5x5x5)</value>
</data>
<data name="ChatBot.AntiAfk.Command" xml:space="preserve">
<value>Command to send to the server.</value>
</data>
<data name="ChatBot.AntiAfk.Delay" xml:space="preserve">
<value>The time interval for execution. (in seconds)</value>
</data>
<data name="ChatBot.AntiAfk.Use_Sneak" xml:space="preserve">
<value>Whether to sneak when sending the command.</value>
</data>
<data name="ChatBot.AntiAfk.Use_Terrain_Handling" xml:space="preserve">
<value>Use terrain handling to enable the bot to move around.</value>
</data>
<data name="ChatBot.AntiAfk.Walk_Range" xml:space="preserve">
<value>The range the bot can move around randomly (Note: the bigger the range, the slower the bot will be)</value>
</data>
<data name="ChatBot.AntiAfk.Walk_Retries" xml:space="preserve">
<value>How many times can the bot fail trying to move before using the command method.</value>
</data>
<data name="ChatBot.AutoAttack" xml:space="preserve">
<value>Automatically attack hostile mobs around you
You need to enable Entity Handling to use this bot
/!\ Make sure server rules allow your planned use of AutoAttack
/!\ SERVER PLUGINS may consider AutoAttack to be a CHEAT MOD and TAKE ACTION AGAINST YOUR ACCOUNT so DOUBLE CHECK WITH SERVER RULES!</value>
</data>
<data name="ChatBot.AutoAttack.Attack_Hostile" xml:space="preserve">
<value>Allow attacking hostile mobs.</value>
</data>
<data name="ChatBot.AutoAttack.Attack_Passive" xml:space="preserve">
<value>Allow attacking passive mobs.</value>
</data>
<data name="ChatBot.AutoAttack.Cooldown_Time" xml:space="preserve">
<value>How long to wait between each attack. Set "Custom = false" to let MCC calculate it.</value>
</data>
<data name="ChatBot.AutoAttack.Entites_List" xml:space="preserve">
<value>All entity types can be found here: https://mccteam.github.io/r/entity/#L15</value>
</data>
<data name="ChatBot.AutoAttack.Interaction" xml:space="preserve">
<value>Possible values: "Interact", "Attack" (default), "InteractAt" (Interact and Attack).</value>
</data>
<data name="ChatBot.AutoAttack.List_Mode" xml:space="preserve">
<value>Wether to treat the entities list as a "whitelist" or as a "blacklist".</value>
</data>
<data name="ChatBot.AutoAttack.Mode" xml:space="preserve">
<value>"single" or "multi". single target one mob per attack. multi target all mobs in range per attack</value>
</data>
<data name="ChatBot.AutoAttack.Priority" xml:space="preserve">
<value>"health" or "distance". Only needed when using single mode</value>
</data>
<data name="ChatBot.AutoCraft" xml:space="preserve">
<value>Automatically craft items in your inventory
See https://mccteam.github.io/g/bots/#auto-craft for how to use
You need to enable Inventory Handling to use this bot
You should also enable Terrain and Movements if you need to use a crafting table</value>
</data>
<data name="ChatBot.AutoCraft.CraftingTable" xml:space="preserve">
<value>Location of the crafting table if you intended to use it. Terrain and movements must be enabled.</value>
</data>
<data name="ChatBot.AutoCraft.OnFailure" xml:space="preserve">
<value>What to do on crafting failure, "abort" or "wait".</value>
</data>
<data name="ChatBot.AutoCraft.Recipes" xml:space="preserve">
<value>Recipes.Name: The name can be whatever you like and it is used to represent the recipe.
Recipes.Type: crafting table type: "player" or "table"
Recipes.Result: the resulting item
Recipes.Slots: All slots, counting from left to right, top to bottom. Please fill in "Null" for empty slots.
For the naming of the items, please see: https://mccteam.github.io/r/item/#L12</value>
</data>
<data name="ChatBot.AutoDig" xml:space="preserve">
<value>Auto-digging blocks.
You need to enable Terrain Handling to use this bot
You can use "/digbot start" and "/digbot stop" to control the start and stop of AutoDig.
Since MCC does not yet support accurate calculation of the collision volume of blocks, all blocks are considered as complete cubes when obtaining the position of the lookahead.
For the naming of the block, please see https://mccteam.github.io/r/block/#L15</value>
</data>
<data name="ChatBot.AutoDig.Auto_Start_Delay" xml:space="preserve">
<value>How many seconds to wait after entering the game to start digging automatically, set to -1 to disable automatic start.</value>
</data>
<data name="ChatBot.AutoDig.Auto_Tool_Switch" xml:space="preserve">
<value>Automatically switch to the appropriate tool.</value>
</data>
<data name="ChatBot.AutoDig.Dig_Timeout" xml:space="preserve">
<value>Mining a block for more than "Dig_Timeout" seconds will be considered a timeout.</value>
</data>
<data name="ChatBot.AutoDig.Drop_Low_Durability_Tools" xml:space="preserve">
<value>Whether to drop the current tool when its durability is too low.</value>
</data>
<data name="ChatBot.AutoDig.Durability_Limit" xml:space="preserve">
<value>Will not use tools with less durability than this. Set to zero to disable this feature.</value>
</data>
<data name="ChatBot.AutoDig.List_Type" xml:space="preserve">
<value>Wether to treat the blocks list as a "whitelist" or as a "blacklist".</value>
</data>
<data name="ChatBot.AutoDig.Locations" xml:space="preserve">
<value>The position of the blocks when using "fixedpos" or "both" mode.</value>
</data>
<data name="ChatBot.AutoDig.Location_Order" xml:space="preserve">
<value>"distance" or "index", When using the "fixedpos" mode, the blocks are determined by distance to the player, or by the order in the list.</value>
</data>
<data name="ChatBot.AutoDig.Log_Block_Dig" xml:space="preserve">
<value>Whether to output logs when digging blocks.</value>
</data>
<data name="ChatBot.AutoDig.Mode" xml:space="preserve">
<value>"lookat", "fixedpos" or "both". Digging the block being looked at, the block in a fixed position, or the block that needs to be all met.</value>
</data>
<data name="ChatBot.AutoDrop" xml:space="preserve">
<value>Automatically drop items in inventory
You need to enable Inventory Handling to use this bot
See this file for an up-to-date list of item types you can use with this bot: https://mccteam.github.io/r/item/#L12</value>
</data>
<data name="ChatBot.AutoDrop.Mode" xml:space="preserve">
<value>"include", "exclude" or "everything". Include: drop item IN the list. Exclude: drop item NOT IN the list</value>
</data>
<data name="ChatBot.AutoEat" xml:space="preserve">
<value>Automatically eat food when your Hunger value is low
You need to enable Inventory Handling to use this bot</value>
</data>
<data name="ChatBot.AutoFishing" xml:space="preserve">
<value>Automatically catch fish using a fishing rod
Guide: https://mccteam.github.io/g/bots/#auto-fishing
You can use "/fish" to control the bot manually.
/!\ Make sure server rules allow automated farming before using this bot</value>
</data>
<data name="ChatBot.AutoFishing.Antidespawn" xml:space="preserve">
<value>Keep it as false if you have not changed it before.</value>
</data>
<data name="ChatBot.AutoFishing.Auto_Rod_Switch" xml:space="preserve">
<value>Switch to a new rod from inventory after the current rod is unavailable.</value>
</data>
<data name="ChatBot.AutoFishing.Auto_Start" xml:space="preserve">
<value>Whether to start fishing automatically after entering a world.</value>
</data>
<data name="ChatBot.AutoFishing.Cast_Delay" xml:space="preserve">
<value>How soon to re-cast after successful fishing.</value>
</data>
<data name="ChatBot.AutoFishing.Durability_Limit" xml:space="preserve">
<value>Will not use rods with less durability than this (full durability is 64). Set to zero to disable this feature.</value>
</data>
<data name="ChatBot.AutoFishing.Enable_Move" xml:space="preserve">
<value>This allows the player to change position/facing after each fish caught.</value>
</data>
<data name="ChatBot.AutoFishing.Fishing_Delay" xml:space="preserve">
<value>How long after entering the game to start fishing (seconds).</value>
</data>
<data name="ChatBot.AutoFishing.Fishing_Timeout" xml:space="preserve">
<value>Fishing timeout (seconds). Timeout will trigger a re-cast.</value>
</data>
<data name="ChatBot.AutoFishing.Hook_Threshold" xml:space="preserve">
<value>A "stationary" hook that moves above this threshold in the Y-axis will be considered to have caught a fish.</value>
</data>
<data name="ChatBot.AutoFishing.Log_Fish_Bobber" xml:space="preserve">
<value>Used to adjust the above two thresholds, which when enabled will print the change in the position of the fishhook entity upon receipt of its movement packet.</value>
</data>
<data name="ChatBot.AutoFishing.Mainhand" xml:space="preserve">
<value>Use the mainhand or the offhand to hold the rod.</value>
</data>
<data name="ChatBot.AutoFishing.Movements" xml:space="preserve">
<value>It will move in order "1-&gt;2-&gt;3-&gt;4-&gt;3-&gt;2-&gt;1-&gt;2-&gt;..." and can change position or facing or both each time. It is recommended to change the facing only.</value>
</data>
<data name="ChatBot.AutoFishing.Stationary_Threshold" xml:space="preserve">
<value>Hook movement in the X and Z axis less than this value will be considered stationary.</value>
</data>
<data name="ChatBot.AutoRelog" xml:space="preserve">
<value>Automatically relog when disconnected by server, for example because the server is restating
/!\ Use Ignore_Kick_Message=true at own risk! Server staff might not appreciate if you auto-relog on manual kicks</value>
</data>
<data name="ChatBot.AutoRelog.Delay" xml:space="preserve">
<value>The delay time before joining the server. (in seconds)</value>
</data>
<data name="ChatBot.AutoRelog.Ignore_Kick_Message" xml:space="preserve">
<value>When set to true, autorelog will reconnect regardless of kick messages.</value>
</data>
<data name="ChatBot.AutoRelog.Kick_Messages" xml:space="preserve">
<value>If the kickout message matches any of the strings, then autorelog will be triggered.</value>
</data>
<data name="ChatBot.AutoRelog.Retries" xml:space="preserve">
<value>Retries when failing to relog to the server. use -1 for unlimited retries.</value>
</data>
<data name="ChatBot.AutoRespond" xml:space="preserve">
<value>Run commands or send messages automatically when a specified pattern is detected in chat
Server admins can spoof chat messages (/nick, /tellraw) so keep this in mind when implementing AutoRespond rules
/!\ This bot may get spammy depending on your rules, although the global messagecooldown setting can help you avoiding accidental spam</value>
</data>
<data name="ChatBot.AutoRespond.Match_Colors" xml:space="preserve">
<value>Do not remove colors from text (Note: Your matches will have to include color codes (ones using the § character) in order to work)</value>
</data>
<data name="ChatBot.ChatLog" xml:space="preserve">
<value>Logs chat messages in a file on disk.</value>
</data>
<data name="ChatBot.DiscordBridge" xml:space="preserve">
<value>This bot allows you to send and recieve messages and commands via a Discord channel.
For Setup you can either use the documentation or read here (Documentation has images).
Documentation: https://mccteam.github.io/g/bots/#discord-bridge
Setup:
First you need to create a Bot on the Discord Developers Portal, here is a video tutorial: https://www.youtube.com/watch?v=2FgMnZViNPA .
/!\ IMPORTANT /!\: When creating a bot, you MUST ENABLE "Message Content Intent", "Server Members Intent" and "Presence Intent" in order for bot to work! Also follow along carefully do not miss any steps!
When making a bot, copy the generated token and paste it here in "Token" field (tokens are important, keep them safe).
Copy the "Application ID" and go to: https://discordapi.com/permissions.html .
Paste the id you have copied and check the "Administrator" field in permissions, then click on the link at the bottom.
This will open an invitation menu with your servers, choose the server you want to invite the bot on and invite him.
Once you've invited the bot, go to your Discord client and go to Settings -&gt; Advanced and Enable "Developer Mode".
Exit the settings and right click on a server you have invited the bot to in the server list, then click "Copy ID", and paste the id here in "GuildId".
Then right click on a channel where you want to interact with the bot and again right click -&gt; "Copy ID", pase the copied id here in "ChannelId".
And for the end, send a message in the channel, right click on your nick and again right click -&gt; "Copy ID", then paste the id here in "OwnersIds".
How to use:
To execute an MCC command, prefix it with a dot ".", example: ".move 143 64 735" .
To send a message, simply type it out and hit enter.</value>
</data>
<data name="ChatBot.DiscordBridge.ChannelId" xml:space="preserve">
<value>The ID of a channel where you want to interact with the MCC using the bot.</value>
</data>
<data name="ChatBot.DiscordBridge.Formats" xml:space="preserve">
<value>Message formats
Words wrapped with { and } are going to be replaced during the code execution, do not change them!
For example. {message} is going to be replace with an actual message, {username} will be replaced with an username, {timestamp} with the current time.
For Discord message formatting, check the following: https://mccteam.github.io/r/dc-fmt.html</value>
</data>
<data name="ChatBot.DiscordBridge.GuildId" xml:space="preserve">
<value>The ID of a server/guild where you have invited the bot to.</value>
</data>
<data name="ChatBot.DiscordBridge.MessageSendTimeout" xml:space="preserve">
<value>How long to wait (in seconds) if a message can not be sent to discord before canceling the task (minimum 1 second).</value>
</data>
<data name="ChatBot.DiscordBridge.OwnersIds" xml:space="preserve">
<value>A list of IDs of people you want to be able to interact with the MCC using the bot.</value>
</data>
<data name="ChatBot.DiscordBridge.Token" xml:space="preserve">
<value>Your Discord Bot token.</value>
</data>
<data name="ChatBot.Farmer" xml:space="preserve">
<value>Automatically farms crops for you (plants, breaks and bonemeals them).
Crop types available: Beetroot, Carrot, Melon, Netherwart, Pumpkin, Potato, Wheat.
Usage: "/farmer start" command and "/farmer stop" command.
NOTE: This a newly added bot, it is not perfect and was only tested in 1.19.2, there are some minor issues like not being able to bonemeal carrots/potatoes sometimes.
or bot jumps onto the farm land and breaks it (this happens rarely but still happens). We are looking forward at improving this.
It is recommended to keep the farming area walled off and flat to avoid the bot jumping.
Also, if you have your farmland that is one block high, make it 2 or more blocks high so the bot does not fall through, as it can happen sometimes when the bot reconnects.
The bot also does not pickup all items if they fly off to the side, we have a plan to implement this option in the future as well as drop off and bonemeal refill chest(s).</value>
</data>
<data name="ChatBot.Farmer.Delay_Between_Tasks" xml:space="preserve">
<value>Delay between tasks in seconds (Minimum 1 second)</value>
</data>
<data name="ChatBot.FollowPlayer" xml:space="preserve">
<value>Enabled you to make the bot follow you
NOTE: This is an experimental feature, the bot can be slow at times, you need to walk with a normal speed and to sometimes stop for it to be able to keep up with you
It's similar to making animals follow you when you're holding food in your hand.
This is due to a slow pathfinding algorithm, we're working on getting a better one
You can tweak the update limit and find what works best for you. (NOTE: Do not but a very low one, because you might achieve the opposite,
this might clog the thread for terain handling) and thus slow the bot even more.
/!\ Make sure server rules allow an option like this in the rules of the server before using this bot</value>
</data>
<data name="ChatBot.FollowPlayer.Stop_At_Distance" xml:space="preserve">
<value>Do not follow the player if he is in the range of 3 blocks (prevents the bot from pushing a player in an infinite loop)</value>
</data>
<data name="ChatBot.FollowPlayer.Update_Limit" xml:space="preserve">
<value>The rate at which the bot does calculations (in seconds) (You can tweak this if you feel the bot is too slow)</value>
</data>
<data name="ChatBot.HangmanGame" xml:space="preserve">
<value>A small game to demonstrate chat interactions. Players can guess mystery words one letter at a time.
You need to have ChatFormat working correctly and add yourself in botowners to start the game with /tell &lt;bot username&gt; start
/!\ This bot may get a bit spammy if many players are interacting with it</value>
</data>
<data name="ChatBot.Mailer" xml:space="preserve">
<value>Relay messages between players and servers, like a mail plugin
This bot can store messages when the recipients are offline, and send them when they join the server
/!\ Server admins can spoof PMs (/tellraw, /nick) so enable this bot only if you trust server admins</value>
</data>
<data name="ChatBot.Map" xml:space="preserve">
<value>Allows you to render maps in the console and into images (which can be then sent to Discord using Discord Bridge Chat Bot)
This is useful for solving captchas which use maps
The maps are rendered into Rendered_Maps folder if the Save_To_File is enabled.
NOTE:
If some servers have a very short time for solving captchas, enabe Auto_Render_On_Update to see them immediatelly in the console.
/!\ Make sure server rules allow bots to be used on the server, or you risk being punished.</value>
</data>
<data name="ChatBot.Map.Auto_Render_On_Update" xml:space="preserve">
<value>Automatically render the map once it is received or updated from/by the server</value>
</data>
<data name="ChatBot.Map.Delete_All_On_Unload" xml:space="preserve">
<value>Delete all rendered maps on unload/reload or when you launch the MCC again.</value>
</data>
<data name="ChatBot.Map.Notify_On_First_Update" xml:space="preserve">
<value>Get a notification when you have gotten a map from the server for the first time</value>
</data>
<data name="ChatBot.Map.Rasize_Rendered_Image" xml:space="preserve">
<value>Resize an rendered image, this is useful when images that are rendered are small and when are being sent to Discord.</value>
</data>
<data name="ChatBot.Map.Render_In_Console" xml:space="preserve">
<value>Whether to render the map in the console.</value>
</data>
<data name="ChatBot.Map.Resize_To" xml:space="preserve">
<value>The size that a rendered image should be resized to, in pixels (eg. 512).</value>
</data>
<data name="ChatBot.Map.Save_To_File" xml:space="preserve">
<value>Whether to store the rendered map as a file (You need this setting if you want to get a map on Discord using Discord Bridge).</value>
</data>
<data name="ChatBot.Map.Send_Rendered_To_Bridges" xml:space="preserve">
<value>Send a rendered map (saved to a file) to a Discord or a Telegram channel via the Discord or Telegram Bride chat bot (The Discord/Telegram Bridge chat bot must be enabled and configured!)
You need to enable Save_To_File in order for this to work.
We also recommend turning on resizing.</value>
</data>
<data name="ChatBot.PlayerListLogger" xml:space="preserve">
<value>Log the list of players periodically into a textual file.</value>
</data>
<data name="ChatBot.PlayerListLogger.Delay" xml:space="preserve">
<value>(In seconds)</value>
</data>
<data name="ChatBot.RemoteControl" xml:space="preserve">
<value>Send MCC console commands to your bot through server PMs (/tell)
You need to have ChatFormat working correctly and add yourself in botowners to use the bot
/!\ Server admins can spoof PMs (/tellraw, /nick) so enable RemoteControl only if you trust server admins</value>
</data>
<data name="ChatBot.ReplayCapture" xml:space="preserve">
<value>Enable recording of the game (/replay start) and replay it later using the Replay Mod (https://www.replaymod.com/)
Please note that due to technical limitations, the client player (you) will not be shown in the replay file
/!\ You SHOULD use /replay stop or exit the program gracefully with /quit OR THE REPLAY FILE MAY GET CORRUPT!</value>
</data>
<data name="ChatBot.ReplayCapture.Backup_Interval" xml:space="preserve">
<value>How long should replay file be auto-saved, in seconds. Use -1 to disable.</value>
</data>
<data name="ChatBot.ScriptScheduler" xml:space="preserve">
<value>Schedule commands and scripts to launch on various events such as server join, date/time or time interval
See https://mccteam.github.io/g/bots/#script-scheduler for more info</value>
</data>
<data name="ChatBot.TelegramBridge" xml:space="preserve">
<value>This bot allows you to send and receive messages and commands via a Telegram Bot DM or to receive messages in a Telegram channel.
/!\ NOTE: You can't send messages and commands from a group channel, you can only send them in the bot DM, but you can get the messages from the client in a group channel.
-----------------------------------------------------------
Setup:
First you need to create a Telegram bot and obtain an API key, to do so, go to Telegram and find @botfather
Click on "Start" button and read the bot reply, then type "/newbot", the Botfather will guide you through the bot creation.
Once you create the bot, copy the API key that you have gotten, and put it into the "Token" field of "ChatBot.TelegramBridge" section (this section).
/!\ Do not share this token with anyone else as it will give them the control over your bot. Save it securely.
Then launch the client and go to Telegram, find your newly created bot by searching for it with its username, and open a DM with it.
Click on "Start" button and type and send the following command ".chatid" to obtain the chat id.
Copy the chat id number (eg. 2627844670) and paste it in the "ChannelId" field and add it to the "Authorized_Chat_Ids" field (in this section) (an id in "Authorized_Chat_Ids" field is a number/long, not a string!), then save the file.
Now you can use the bot using it's DM.
/!\ If you do not add the id of your chat DM with the bot to the "Authorized_Chat_Ids" field, ayone who finds your bot via search will be able to execute commands and send messages!
/!\ An id pasted in to the "Authorized_Chat_Ids" should be a number/long, not a string!
-----------------------------------------------------------
NOTE: If you want to recieve messages to a group channel instead, make the channel temporarely public, invite the bot to it and make it an administrator, then set the channel to private if you want.
Then set the "ChannelId" field to the @ of your channel (you must include the @ in the settings, eg. "@mysupersecretchannel"), this is the username you can see in the invite link of the channel.
/!\ Only include the username with @ prefix, do not include the rest of the link. Example if you have "https://t.me/mysupersecretchannel", the "ChannelId" will be "@mysupersecretchannel".
/!\ Note that you will not be able to send messages to the client from a group channel!
-----------------------------------------------------------
How to use the bot:
To execute an MCC command, prefix it with a dot ".", example: ".move 143 64 735" .
To send a message, simply type it out and hit enter.</value>
</data>
<data name="ChatBot.TelegramBridge.Authorized_Chat_Ids" xml:space="preserve">
<value>A list of Chat IDs that are allowed to send messages and execute commands. To get an id of your chat DM with the bot use ".chatid" bot command in Telegram.</value>
</data>
<data name="ChatBot.TelegramBridge.ChannelId" xml:space="preserve">
<value>An ID of a channel where you want to interact with the MCC using the bot.</value>
</data>
<data name="ChatBot.TelegramBridge.Formats" xml:space="preserve">
<value>Message formats
Words wrapped with { and } are going to be replaced during the code execution, do not change them!
For example. {message} is going to be replace with an actual message, {username} will be replaced with an username, {timestamp} with the current time.
For Telegram message formatting, check the following: https://mccteam.github.io/r/tg-fmt.html</value>
</data>
<data name="ChatBot.TelegramBridge.MessageSendTimeout" xml:space="preserve">
<value>How long to wait (in seconds) if a message can not be sent to Telegram before canceling the task (minimum 1 second).</value>
</data>
<data name="ChatBot.TelegramBridge.Token" xml:space="preserve">
<value>Your Telegram Bot token.</value>
</data>
<data name="ChatFormat" xml:space="preserve">
<value>MCC does it best to detect chat messages, but some server have unusual chat formats
When this happens, you'll need to configure chat format below, see https://mccteam.github.io/g/conf/#chat-format-section</value>
</data>
<data name="ChatFormat.Builtins" xml:space="preserve">
<value>MCC support for common message formats. Set "false" to avoid conflicts with custom formats.</value>
</data>
<data name="ChatFormat.UserDefined" xml:space="preserve">
<value>Whether to use the custom regular expressions below for detection.</value>
</data>
<data name="Head" xml:space="preserve">
<value>Startup Config File
Please do not record extraneous data in this file as it will be overwritten by MCC.
New to Minecraft Console Client? Check out this document: https://mccteam.github.io/g/conf.html
Want to upgrade to a newer version? See https://github.com/MCCTeam/Minecraft-Console-Client/#download</value>
</data>
<data name="Logging" xml:space="preserve">
<value>This setting affects only the messages in the console.</value>
</data>
<data name="Logging.ChatFilter" xml:space="preserve">
<value>Regex for filtering chat message.</value>
</data>
<data name="Logging.ChatMessages" xml:space="preserve">
<value>Show server chat messages.</value>
</data>
<data name="Logging.DebugFilter" xml:space="preserve">
<value>Regex for filtering debug message.</value>
</data>
<data name="Logging.DebugMessages" xml:space="preserve">
<value>Please enable this before submitting bug reports. Thanks!</value>
</data>
<data name="Logging.ErrorMessages" xml:space="preserve">
<value>Show error messages.</value>
</data>
<data name="Logging.FilterMode" xml:space="preserve">
<value>"disable" or "blacklist" OR "whitelist". Blacklist hide message match regex. Whitelist show message match regex.</value>
</data>
<data name="Logging.InfoMessages" xml:space="preserve">
<value>Informative messages. (i.e Most of the message from MCC)</value>
</data>
<data name="Logging.LogFile" xml:space="preserve">
<value>Log file name.</value>
</data>
<data name="Logging.LogToFile" xml:space="preserve">
<value>Write log messages to file.</value>
</data>
<data name="Logging.PrependTimestamp" xml:space="preserve">
<value>Prepend timestamp to messages in log file.</value>
</data>
<data name="Logging.SaveColorCodes" xml:space="preserve">
<value>Keep color codes in the saved text.(look like "§b")</value>
</data>
<data name="Logging.WarningMessages" xml:space="preserve">
<value>Show warning messages.</value>
</data>
<data name="Main.Advanced" xml:space="preserve">
<value>Make sure you understand what each setting does before changing anything!</value>
</data>
<data name="Main.Advanced.account_list" xml:space="preserve">
<value>AccountList: It allows a fast account switching without directly using the credentials
Usage examples: "/tell &lt;mybot&gt; reco Player2", "/connect &lt;serverip&gt; Player1"</value>
</data>
<data name="Main.Advanced.auto_respawn" xml:space="preserve">
<value>Toggle auto respawn if client player was dead (make sure your spawn point is safe).</value>
</data>
<data name="Main.Advanced.bot_owners" xml:space="preserve">
<value>Set the owner of the bot. /!\ Server admins can impersonate owners!</value>
</data>
<data name="Main.Advanced.brand_info" xml:space="preserve">
<value>Use "mcc", "vanilla" or "none". This is how MCC identifies itself to the server.</value>
</data>
<data name="Main.Advanced.chatbot_log_file" xml:space="preserve">
<value>Leave empty for no logfile.</value>
</data>
<data name="Main.Advanced.enable_emoji" xml:space="preserve">
<value>If turned off, the emoji will be replaced with a simpler character (for /chunk status).</value>
</data>
<data name="Main.Advanced.entity_handling" xml:space="preserve">
<value>Toggle entity handling.</value>
</data>
<data name="Main.Advanced.exit_on_failure" xml:space="preserve">
<value>Whether to exit directly when an error occurs, for using MCC in non-interactive scripts.</value>
</data>
<data name="Main.Advanced.internal_cmd_char" xml:space="preserve">
<value>Use "none", "slash"(/) or "backslash"(\).</value>
</data>
<data name="Main.Advanced.inventory_handling" xml:space="preserve">
<value>Toggle inventory handling.</value>
</data>
<data name="Main.Advanced.language" xml:space="preserve">
<value>Fill in with in-game locale code, check https://mccteam.github.io/r/l-code.html</value>
</data>
<data name="Main.Advanced.LoadMccTrans" xml:space="preserve">
<value>Load translations applied to MCC when available, turn it off to use English only.</value>
</data>
<data name="Main.Advanced.mc_forge" xml:space="preserve">
<value>Use "auto", "no" or "force". Force-enabling only works for MC 1.13+.</value>
</data>
<data name="Main.Advanced.mc_version" xml:space="preserve">
<value>Use "auto" or "1.X.X" values. Allows to skip server info retrieval.</value>
</data>
<data name="Main.Advanced.message_cooldown" xml:space="preserve">
<value>Controls the minimum interval (in seconds) between sending each message to the server.</value>
</data>
<data name="Main.Advanced.minecraft_realms" xml:space="preserve">
<value>Enable support for joining Minecraft Realms worlds.</value>
</data>
<data name="Main.Advanced.MinTerminalHeight" xml:space="preserve">
<value>The minimum height to use when calculating the image size from the height of the terminal.</value>
</data>
<data name="Main.Advanced.MinTerminalWidth" xml:space="preserve">
<value>The minimum width used when calculating the image size from the width of the terminal.</value>
</data>
<data name="Main.Advanced.movement_speed" xml:space="preserve">
<value>A movement speed higher than 2 may be considered cheating.</value>
</data>
<data name="Main.Advanced.move_head_while_walking" xml:space="preserve">
<value>Enable head movement while walking to avoid anti-cheat triggers.</value>
</data>
<data name="Main.Advanced.player_head_icon" xml:space="preserve">
<value>Only works on Windows XP-8 or Windows 10 with old console.</value>
</data>
<data name="Main.Advanced.private_msgs_cmd_name" xml:space="preserve">
<value>For remote control of the bot.</value>
</data>
<data name="Main.Advanced.profilekey_cache" xml:space="preserve">
<value>How to retain profile key. Use "none", "memory" or "disk".</value>
</data>
<data name="Main.Advanced.resolve_srv_records" xml:space="preserve">
<value>Use "no", "fast" (5s timeout), or "yes". Required for joining some servers.</value>
</data>
<data name="Main.Advanced.script_cache" xml:space="preserve">
<value>Cache compiled scripts for faster load on low-end devices.</value>
</data>
<data name="Main.Advanced.server_list" xml:space="preserve">
<value>ServerList: It allows an easier and faster server switching with short aliases instead of full server IP
Aliases cannot contain dots or spaces, and the name "localhost" cannot be used as an alias.
Usage examples: "/tell &lt;mybot&gt; connect Server1", "/connect Server2"</value>
</data>
<data name="Main.Advanced.session_cache" xml:space="preserve">
<value>How to retain session tokens. Use "none", "memory" or "disk".</value>
</data>
<data name="Main.Advanced.show_chat_links" xml:space="preserve">
<value>Decode links embedded in chat messages and show them in console.</value>
</data>
<data name="Main.Advanced.show_inventory_layout" xml:space="preserve">
<value>Show inventory layout as ASCII art in inventory command.</value>
</data>
<data name="Main.Advanced.show_system_messages" xml:space="preserve">
<value>System messages for server ops.</value>
</data>
<data name="Main.Advanced.show_xpbar_messages" xml:space="preserve">
<value>Messages displayed above xp bar, set this to false in case of xp bar spam.</value>
</data>
<data name="Main.Advanced.temporary_fix_badpacket" xml:space="preserve">
<value>Temporary fix for Badpacket issue on some servers.</value>
</data>
<data name="Main.Advanced.TerminalColorDepth" xml:space="preserve">
<value>Use "none", "bit_4", "bit_8" or "bit_24". This can be checked by opening the debug log.</value>
</data>
<data name="Main.Advanced.terrain_and_movements" xml:space="preserve">
<value>Uses more ram, cpu, bandwidth but allows you to move around.</value>
</data>
<data name="Main.Advanced.timeout" xml:space="preserve">
<value>Customize the TCP connection timeout with the server. (in seconds)</value>
</data>
<data name="Main.Advanced.timestamps" xml:space="preserve">
<value>Prepend timestamps to chat messages.</value>
</data>
<data name="Main.General.account" xml:space="preserve">
<value>Login=Email or Name. Use "-" as password for offline mode. Leave blank to prompt user on startup.</value>
</data>
<data name="Main.General.login" xml:space="preserve">
<value>The address of the game server, "Host" can be filled in with domain name or IP address. (The "Port" field can be deleted, it will be resolved automatically)</value>
</data>
<data name="Main.General.method" xml:space="preserve">
<value>Microsoft Account sign-in method: "mcc" OR "browser". If the login always fails, please try to use the "browser" once.</value>
</data>
<data name="Main.General.server_info" xml:space="preserve">
<value>Account type: "mojang" OR "microsoft". Also affects interactive login in console.</value>
</data>
<data name="MCSettings" xml:space="preserve">
<value>Settings below are sent to the server and only affect server-side things like your skin.</value>
</data>
<data name="MCSettings.ChatColors" xml:space="preserve">
<value>Allows disabling chat colors server-side.</value>
</data>
<data name="MCSettings.ChatMode" xml:space="preserve">
<value>Use "enabled", "commands", or "disabled". Allows to mute yourself...</value>
</data>
<data name="MCSettings.Difficulty" xml:space="preserve">
<value>MC 1.7- difficulty. "peaceful", "easy", "normal", "difficult".</value>
</data>
<data name="MCSettings.Enabled" xml:space="preserve">
<value>If disabled, settings below are not sent to the server.</value>
</data>
<data name="MCSettings.Locale" xml:space="preserve">
<value>Use any language implemented in Minecraft.</value>
</data>
<data name="MCSettings.MainHand" xml:space="preserve">
<value>MC 1.9+ main hand. "left" or "right".</value>
</data>
<data name="MCSettings.RenderDistance" xml:space="preserve">
<value>Value range: [0 - 255].</value>
</data>
<data name="Proxy" xml:space="preserve">
<value>Connect to a server via a proxy instead of connecting directly
If Mojang session services are blocked on your network, set Enabled_Login=true to login using proxy.
If the connection to the Minecraft game server is blocked by the firewall, set Enabled_Ingame=true to use a proxy to connect to the game server.
/!\ Make sure your server rules allow Proxies or VPNs before setting enabled=true, or you may face consequences!</value>
</data>
<data name="Proxy.Enabled_Ingame" xml:space="preserve">
<value>Whether to connect to the game server through a proxy.</value>
</data>
<data name="Proxy.Enabled_Login" xml:space="preserve">
<value>Whether to connect to the login server through a proxy.</value>
</data>
<data name="Proxy.Enabled_Update" xml:space="preserve">
<value>Whether to download MCC updates via proxy.</value>
</data>
<data name="Proxy.Password" xml:space="preserve">
<value>Only required for password-protected proxies.</value>
</data>
<data name="Proxy.Proxy_Type" xml:space="preserve">
<value>Supported types: "HTTP", "SOCKS4", "SOCKS4a", "SOCKS5".</value>
</data>
<data name="Proxy.Server" xml:space="preserve">
<value>Proxy server must allow HTTPS for login, and non-443 ports for playing.</value>
</data>
<data name="Proxy.Username" xml:space="preserve">
<value>Only required for password-protected proxies.</value>
</data>
<data name="Signature" xml:space="preserve">
<value>Chat signature related settings (affects minecraft 1.19+)</value>
</data>
<data name="Signature.LoginWithSecureProfile" xml:space="preserve">
<value>Microsoft accounts only. If disabled, will not be able to sign chat and join servers configured with "enforce-secure-profile=true"</value>
</data>
<data name="Signature.MarkIllegallySignedMsg" xml:space="preserve">
<value>Use red    color block to mark chat without legitimate signature</value>
</data>
<data name="Signature.MarkLegallySignedMsg" xml:space="preserve">
<value>Use green  color block to mark chat with legitimate signatures</value>
</data>
<data name="Signature.MarkModifiedMsg" xml:space="preserve">
<value>Use yellow color block to mark chat that have been modified by the server.</value>
</data>
<data name="Signature.MarkSystemMessage" xml:space="preserve">
<value>Use gray   color block to mark system message (always without signature)</value>
</data>
<data name="Signature.ShowIllegalSignedChat" xml:space="preserve">
<value>Whether to display chat and messages in commands without legal signatures</value>
</data>
<data name="Signature.ShowModifiedChat" xml:space="preserve">
<value>Set to true to display messages modified by the server, false to display the original signed messages</value>
</data>
<data name="Signature.SignChat" xml:space="preserve">
<value>Whether to sign the chat send from MCC</value>
</data>
<data name="Signature.SignMessageInCommand" xml:space="preserve">
<value>Whether to sign the messages contained in the commands sent by MCC. For example, the message in "/msg" and "/me"</value>
</data>
</root>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.IO; using System.IO;

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@ -100,12 +100,12 @@ namespace MinecraftClient.Scripting
/// NOTE: Chat messages cannot be sent at this point in the login process. /// NOTE: Chat messages cannot be sent at this point in the login process.
/// If you want to send a message when the bot is loaded, use AfterGameJoined. /// If you want to send a message when the bot is loaded, use AfterGameJoined.
/// </summary> /// </summary>
public virtual void Initialize(CommandDispatcher<CmdResult> dispatcher) { } public virtual void Initialize() { }
/// <summary> /// <summary>
/// This method is called when the bot is being unloaded, you can use it to free up resources like DB connections /// This method is called when the bot is being unloaded, you can use it to free up resources like DB connections
/// </summary> /// </summary>
public virtual void OnUnload(CommandDispatcher<CmdResult> dispatcher) { } public virtual void OnUnload() { }
/// <summary> /// <summary>
/// Called after the server has been joined successfully and chat messages are able to be sent. /// Called after the server has been joined successfully and chat messages are able to be sent.

View file

@ -1,4 +1,4 @@
/* /*
MIT License MIT License
Copyright (c) 2019 Laurent Kempé Copyright (c) 2019 Laurent Kempé
https://github.com/laurentkempe/DynamicRun/blob/master/LICENSE https://github.com/laurentkempe/DynamicRun/blob/master/LICENSE

Some files were not shown because too many files have changed in this diff Show more