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; } }