Skip to content

Commit

Permalink
[Rules] Add Rule for restricting client versions to world server (#4527)
Browse files Browse the repository at this point in the history
* add rule for supported clients, unsupported client packet

* whitespace

* PR feedback - Update client.cpp

* PR Feedback - Update client.cpp

* Update client.cpp

* Update client.cpp

---------

Co-authored-by: Paul Johnson <[email protected]>
  • Loading branch information
knervous and Paul Johnson authored Nov 12, 2024
1 parent 011e1d0 commit c1df3fb
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
1 change: 1 addition & 0 deletions common/ruletypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ RULE_STRING(World, MOTD, "", "Server MOTD sent on login, change from empty to ha
RULE_STRING(World, Rules, "", "Server Rules, change from empty to have this be used instead of variables table 'rules' value, lines are pipe (|) separated, example: A|B|C")
RULE_BOOL(World, EnableAutoLogin, false, "Enables or disables auto login of characters, allowing people to log characters in directly from loginserver to ingame")
RULE_BOOL(World, EnablePVPRegions, true, "Enables or disables PVP Regions automatically setting your PVP flag")
RULE_STRING(World, SupportedClients, "", "Comma-delimited list of clients to restrict to. Supported values are Titanium | SoF | SoD | UF | RoF | RoF2. Example: Titanium,RoF2")
RULE_CATEGORY_END()

RULE_CATEGORY(Zone)
Expand Down
55 changes: 52 additions & 3 deletions world/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,9 +526,27 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app)
SendEnterWorld(cle->name());
SendPostEnterWorld();
if (!is_player_zoning) {
SendExpansionInfo();
SendCharInfo();
database.LoginIP(cle->AccountID(), long2ip(GetIP()));
const auto supported_clients = RuleS(World, SupportedClients);
bool skip_char_info = false;
if (!supported_clients.empty()) {
const std::string& name = EQ::versions::ClientVersionName(m_ClientVersion);
const auto& clients = Strings::Split(supported_clients, ",");
if (std::find(clients.begin(), clients.end(), name) == clients.end()) {
SendUnsupportedClientPacket(
fmt::format(
"Client Not In Supported List [{}]",
supported_clients
)
);
skip_char_info = true;
}
}

if (!skip_char_info) {
SendExpansionInfo();
SendCharInfo();
database.LoginIP(cle->AccountID(), long2ip(GetIP()));
}
}

cle->SetIP(GetIP());
Expand Down Expand Up @@ -2453,3 +2471,34 @@ void Client::SendGuildTributeOptInToggle(const GuildTributeMemberToggle *in)
QueuePacket(outapp);
safe_delete(outapp);
}

void Client::SendUnsupportedClientPacket(const std::string& message)
{
EQApplicationPacket packet(OP_SendCharInfo, sizeof(CharacterSelect_Struct) + sizeof(CharacterSelectEntry_Struct));

unsigned char* buff_ptr = packet.pBuffer;
auto cs = (CharacterSelect_Struct*) buff_ptr;

cs->CharCount = 1;
cs->TotalChars = 1;

buff_ptr += sizeof(CharacterSelect_Struct);

auto e = (CharacterSelectEntry_Struct*) buff_ptr;

strcpy(e->Name, message.c_str());

e->Race = Race::Human;
e->Class = Class::Warrior;
e->Level = 1;
e->ShroudClass = e->Class;
e->ShroudRace = e->Race;
e->Zone = std::numeric_limits<uint16>::max();
e->Instance = 0;
e->Gender = Gender::Male;
e->GoHome = 0;
e->Tutorial = 0;
e->Enabled = 0;

QueuePacket(&packet);
}
1 change: 1 addition & 0 deletions world/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ class Client {
EQStreamInterface* eqs;
bool CanTradeFVNoDropItem();
void RecordPossibleHack(const std::string& message);
void SendUnsupportedClientPacket(const std::string& message);
};

bool CheckCharCreateInfoSoF(CharCreate_Struct *cc);
Expand Down

0 comments on commit c1df3fb

Please sign in to comment.