Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add legacy shim for chatting (TalkPath) #21

Merged
merged 2 commits into from
Jan 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions config.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ uberdogs:
anonymous: true # Allows un-authenticated clients to communicate with this object.

- id: 4666
class: ChatManager

- id: 4667
class: FriendsManager

# Metrics (Prometheus) configuration.
Expand Down Expand Up @@ -74,6 +77,13 @@ client-agent:
# NOTE: You must build Ardos with ARDOS_USE_LEGACY_CLIENT to use this option.
ud-auth-shim: 4665

# Shim's chat messages from Disney specific clients to an UberDOG.
# The original OTP server intercepted TalkPath_* field updates and
# handled the filtering/broadcasting of those messages on the CA.
# (DoId matches ChatManager defined above.)
# NOTE: You must build Ardos with ARDOS_USE_LEGACY_CLIENT to use this option.
ud-chat-shim: 4666

# The range of channels this CA can allocate.
channels:
min: 1000000000
Expand Down
18 changes: 16 additions & 2 deletions src/clientagent/client_agent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,15 @@ ClientAgent::ClientAgent() {
// UberDOG auth shim.
// This allows clients authenticating over Disney specific login methods to
// authenticate with the cluster.
if (auto shimParam = config["ud-auth-shim"]) {
_udAuthShim = shimParam.as<uint32_t>();
if (auto authShimParam = config["ud-auth-shim"]) {
_udAuthShim = authShimParam.as<uint32_t>();
}

// UberDOG chat shim.
// This allows clients sending chat messages with an unmodified Disney otp.dc
// to have filtering done on an UberDOG (as opposed to none at all.)
if (auto chatShimParam = config["ud-chat-shim"]) {
_udChatShim = chatShimParam.as<uint32_t>();
}

// Socket events.
Expand Down Expand Up @@ -174,6 +181,13 @@ void ClientAgent::FreeChannel(const uint64_t &channel) {
*/
uint32_t ClientAgent::GetAuthShim() const { return _udAuthShim; }

/**
* Returns the DoId of the configured UD Chat Shim (or 0 if none
* is configured).
* @return
*/
uint32_t ClientAgent::GetChatShim() const { return _udChatShim; }

/**
* Returns the configured server version.
* @return
Expand Down
2 changes: 2 additions & 0 deletions src/clientagent/client_agent.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class ClientAgent {
void FreeChannel(const uint64_t &channel);

[[nodiscard]] uint32_t GetAuthShim() const;
[[nodiscard]] uint32_t GetChatShim() const;
[[nodiscard]] std::string GetVersion() const;
[[nodiscard]] uint32_t GetHash() const;
[[nodiscard]] unsigned long GetHeartbeatInterval() const;
Expand Down Expand Up @@ -70,6 +71,7 @@ class ClientAgent {
std::queue<uint64_t> _freedChannels;

uint32_t _udAuthShim = 0;
uint32_t _udChatShim = 0;

prometheus::Counter *_datagramsProcessedCounter = nullptr;
prometheus::Histogram *_datagramsSizeHistogram = nullptr;
Expand Down
42 changes: 42 additions & 0 deletions src/clientagent/client_participant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -923,9 +923,51 @@ void ClientParticipant::HandleClientObjectUpdateField(DatagramIterator &dgi) {
}
}

// Unpack the field data.
std::vector<uint8_t> data;
dgi.UnpackField(field, data);

#ifdef ARDOS_USE_LEGACY_CLIENT
// Do we have a configured legacy chat shim?
uint32_t chatShim = _clientAgent->GetChatShim();
if (chatShim) {
// We do, lets check if the field update relates to talking.
if (field->get_name() == "setTalk" ||
field->get_name() == "setTalkWhisper") {
// It does, we have a TalkPath field update that requires filtering.

// Get the configured shim UberDOG.
DCClass *chatClass = LookupObject(chatShim);
if (!chatClass) {
Logger::Error(std::format(
"[CA] Chat shim DoId: {} is not a configured UberDOG", chatShim));
// Just drop the message to be safe.
return;
}

// Get the field id for the specific talk message from the chat shim.
// This is a 1-1 mapping with the TalkPath_ field names.
DCField *chatField = chatClass->get_field_by_name(field->get_name());
if (!chatField) {
Logger::Error(std::format(
"[CA] Chat shim UberDOG: {} does not define chat field: {}",
chatShim, field->get_name()));
// Just drop the message to be safe.
return;
}

// Send it off to the configured chat shim UberDOG.
auto dg = std::make_shared<Datagram>(chatShim, _channel,
STATESERVER_OBJECT_SET_FIELD);
dg->AddUint32(chatShim);
dg->AddUint16(chatField->get_number());
dg->AddData(data);
PublishDatagram(dg);
return;
}
}
#endif // ARDOS_USE_LEGACY_CLIENT

// Forward the field update to the state server.
auto dg =
std::make_shared<Datagram>(doId, _channel, STATESERVER_OBJECT_SET_FIELD);
Expand Down