diff --git a/Spawner.vcxproj b/Spawner.vcxproj
index 31fd663b..e8a1181a 100644
--- a/Spawner.vcxproj
+++ b/Spawner.vcxproj
@@ -40,6 +40,7 @@
+
diff --git a/YRpp b/YRpp
index 298877c9..fbf870ed 160000
--- a/YRpp
+++ b/YRpp
@@ -1 +1 @@
-Subproject commit 298877c9bf6b5e6ce01bb86cfc7d5046d5ad4d3d
+Subproject commit fbf870edd06a0c9284163edd6a6c912fc9f9af61
diff --git a/src/Main.Config.cpp b/src/Main.Config.cpp
index cef09773..7c4d43fb 100644
--- a/src/Main.Config.cpp
+++ b/src/Main.Config.cpp
@@ -41,6 +41,7 @@ void MainConfig::LoadFromINIFile()
this->DDrawHandlesClose = pINI->ReadBool(pOptionsSection, "DDrawHandlesClose", this->DDrawHandlesClose);
this->SpeedControl = pINI->ReadBool(pOptionsSection, "SpeedControl", this->SpeedControl);
this->AllowTaunts = pINI->ReadBool(pOptionsSection, "AllowTaunts", this->AllowTaunts);
+ this->AllowChat = pINI->ReadBool(pOptionsSection, "AllowChat", this->AllowChat);
}
const char* pVideoSection = "Video";
diff --git a/src/Main.Config.h b/src/Main.Config.h
index b28bfcbf..d065b78d 100644
--- a/src/Main.Config.h
+++ b/src/Main.Config.h
@@ -37,6 +37,7 @@ class MainConfig
int DDrawTargetFPS;
bool AllowTaunts;
+ bool AllowChat;
void LoadFromINIFile();
void ApplyStaticOptions();
@@ -57,5 +58,6 @@ class MainConfig
, DDrawTargetFPS { -1 }
, AllowTaunts { true }
+ , AllowChat { true }
{ }
};
diff --git a/src/Misc/InGameChat.cpp b/src/Misc/InGameChat.cpp
new file mode 100644
index 00000000..a5612081
--- /dev/null
+++ b/src/Misc/InGameChat.cpp
@@ -0,0 +1,94 @@
+/**
+* yrpp-spawner
+*
+* Copyright(C) 2022-present CnCNet
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program.If not, see .
+*/
+
+#include
+#include
+#include
+
+// This corrects the processing of Unicode player names
+// and prohibits incoming messages from players with whom chat is disabled
+
+#pragma pack(push, 1)
+struct GlobalPacket_NetMessage
+{
+ static constexpr reference const Instance {};
+
+ int Command;
+ wchar_t PlayerName[21];
+ byte HouseIndex;
+ byte ChatID;
+ wchar_t Message[112];
+ byte Color;
+ byte CRC;
+};
+#pragma pack(pop)
+
+DEFINE_HOOK(0x48D92B, NetworkCallBack_NetMessage_Print, 0x5)
+{
+ if (!Spawner::Enabled)
+ return 0;
+
+ enum { SkipMessage = 0x48DAD3, PrintMessage = 0x48D937 };
+
+ const int houseIndex = GlobalPacket_NetMessage::Instance->HouseIndex;
+
+ if (houseIndex < 8 && Game::ChatMask[houseIndex])
+ {
+ if (HouseClass::Array->ValidIndex(houseIndex))
+ {
+ HouseClass* pHouse = HouseClass::Array->GetItem(houseIndex);
+
+ GlobalPacket_NetMessage::Instance->Color = (byte)pHouse->ColorSchemeIndex;
+ R->ESI(pHouse->UIName);
+ return PrintMessage;
+ }
+ }
+
+ return SkipMessage;
+}
+
+DEFINE_HOOK(0x48D95B, NetworkCallBack_NetMessage_SetColor, 0x6)
+{
+ if (!Spawner::Enabled)
+ return 0;
+
+ R->EAX(R->ECX());
+ return 0x48D966;
+}
+
+DEFINE_HOOK(0x55EDD2, MessageInput_Write, 0x5)
+{
+ if (!Spawner::Enabled)
+ return 0;
+
+ HouseClass* pHouse = HouseClass::CurrentPlayer;
+ wcscpy_s(GlobalPacket_NetMessage::Instance->PlayerName, pHouse->UIName);
+ GlobalPacket_NetMessage::Instance->HouseIndex = (byte)pHouse->ArrayIndex;
+
+ return 0x55EE00;
+}
+
+DEFINE_HOOK(0x55F0A8, MessageInput_Print, 0x5)
+{
+ if (!Spawner::Enabled)
+ return 0;
+
+ R->EAX(GlobalPacket_NetMessage::Instance->PlayerName);
+ return 0x55F0B2;
+}
diff --git a/src/Spawner/Spawner.Hook.cpp b/src/Spawner/Spawner.Hook.cpp
index 0cd353fa..dc12b780 100644
--- a/src/Spawner/Spawner.Hook.cpp
+++ b/src/Spawner/Spawner.Hook.cpp
@@ -67,11 +67,6 @@ DEFINE_HOOK(0x6BD7CB, WinMain_SpawnerInit, 0x5)
// Set ConnTimeout
Patch::Apply_TYPED(0x6843C7, { Spawner::GetConfig()->ConnTimeout }); // Scenario_Load_Wait
- { // Add support unicode player name in ingame chat
- Patch::Apply_RAW(0x48D930, { 0x8B, 0xC1, 0x90, 0x90, 0x90 }); // mov eax, ecx
- Patch::Apply_RAW(0x55F0AD, { 0x8B, 0xC1, 0x90, 0x90, 0x90 }); // mov eax, ecx
- }
-
// Show GameMode in DiplomacyDialog in Skirmish
Patch::Apply_LJMP(0x658117, 0x658126); // RadarClass_DiplomacyDialog
@@ -82,16 +77,6 @@ DEFINE_HOOK(0x6BD7CB, WinMain_SpawnerInit, 0x5)
return 0;
}
-// Add support unicode player name in ingame chat
-DEFINE_HOOK(0x55EDD2, MessageInput_UnicodePlayerName, 0x5)
-{
- if (!Spawner::Enabled)
- return 0;
-
- wcscpy(reinterpret_cast(0xA8D63C), NodeNameType::Array->GetItem(0)->Name);
- return 0x55EE00;
-}
-
// Display UIGameMode if is set
// Otherwise use mode name from MPModesMD.ini
DEFINE_HOOK(0x65812E, RadarClass__DiplomacyDialog_UIGameMode, 0x6)
diff --git a/src/Spawner/Spawner.cpp b/src/Spawner/Spawner.cpp
index 39474eac..a09b3ad4 100644
--- a/src/Spawner/Spawner.cpp
+++ b/src/Spawner/Spawner.cpp
@@ -300,7 +300,7 @@ bool Spawner::StartNewScenario(const char* pScenarioName)
{
return ScenarioClass::StartScenario(pScenarioName, 0, -1);
}
- else
+ else /* if (SessionClass::IsMultiplayer()) */
{
Spawner::InitNetwork();
if (!ScenarioClass::StartScenario(pScenarioName, 0, -1))
@@ -308,6 +308,19 @@ bool Spawner::StartNewScenario(const char* pScenarioName)
pSession->GameMode = GameMode::LAN;
pSession->CreateConnections();
+
+ if (Main::GetConfig()->AllowChat)
+ {
+ Game::ChatMask[0] = false;
+ Game::ChatMask[1] = false;
+ Game::ChatMask[2] = false;
+ Game::ChatMask[3] = false;
+ Game::ChatMask[4] = false;
+ Game::ChatMask[5] = false;
+ Game::ChatMask[6] = false;
+ Game::ChatMask[7] = false;
+ }
+
return true;
}
}