Support for chat message (WIP)
parent
2a373bbf79
commit
4f9e67d700
|
@ -2816,6 +2816,8 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
|
||||||
|
|
||||||
void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const
|
void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const
|
||||||
{
|
{
|
||||||
|
ImU32 color_bkp = col;
|
||||||
|
|
||||||
if (!text_end)
|
if (!text_end)
|
||||||
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
|
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
|
||||||
|
|
||||||
|
@ -2871,6 +2873,34 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
|
||||||
|
|
||||||
while (s < text_end)
|
while (s < text_end)
|
||||||
{
|
{
|
||||||
|
if (*s == 1)
|
||||||
|
{
|
||||||
|
++s;
|
||||||
|
|
||||||
|
unsigned char color[4];
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; ++i, s+=2)
|
||||||
|
{
|
||||||
|
if (s[0] >= '0' && s[0] <= '9')
|
||||||
|
color[i] = (s[0] - '0') * 16;
|
||||||
|
else if (s[0] >= 'a' && s[0] <= 'f')
|
||||||
|
color[i] = (s[0] - 'a' + 10) * 16;
|
||||||
|
else if (s[0] >= 'A' && s[0] <= 'F')
|
||||||
|
color[i] = (s[0] - 'A' + 10) * 16;
|
||||||
|
|
||||||
|
if (s[1] >= '0' && s[1] <= '9')
|
||||||
|
color[i] += (s[1] - '0');
|
||||||
|
else if (s[1] >= 'a' && s[1] <= 'f')
|
||||||
|
color[i] += (s[1] - 'a' + 10);
|
||||||
|
else if (s[1] >= 'A' && s[1] <= 'F')
|
||||||
|
color[i] += (s[1] - 'A' + 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
col = ImColor(color[0], color[1], color[2], color[3]);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (word_wrap_enabled)
|
if (word_wrap_enabled)
|
||||||
{
|
{
|
||||||
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
|
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
|
||||||
|
|
|
@ -185,6 +185,17 @@ message Friend_Messages {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message Steam_Messages {
|
||||||
|
enum Types {
|
||||||
|
FRIEND_CHAT = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Types type = 1;
|
||||||
|
oneof message_data {
|
||||||
|
bytes message = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
message Common_Message {
|
message Common_Message {
|
||||||
uint64 source_id = 1;
|
uint64 source_id = 1;
|
||||||
uint64 dest_id = 2;
|
uint64 dest_id = 2;
|
||||||
|
@ -200,6 +211,7 @@ message Common_Message {
|
||||||
Friend_Messages friend_messages = 11;
|
Friend_Messages friend_messages = 11;
|
||||||
Network_Old network_old = 12;
|
Network_Old network_old = 12;
|
||||||
Networking_Sockets networking_sockets = 13;
|
Networking_Sockets networking_sockets = 13;
|
||||||
|
Steam_Messages steam_messages = 14;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 source_ip = 128;
|
uint32 source_ip = 128;
|
||||||
|
|
|
@ -533,6 +533,11 @@ void Networking::do_callbacks_message(Common_Message *msg)
|
||||||
PRINT_DEBUG("has_networking_sockets\n");
|
PRINT_DEBUG("has_networking_sockets\n");
|
||||||
run_callbacks(CALLBACK_ID_NETWORKING_SOCKETS, msg);
|
run_callbacks(CALLBACK_ID_NETWORKING_SOCKETS, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (msg->has_steam_messages()) {
|
||||||
|
PRINT_DEBUG("has_steam_messages\n");
|
||||||
|
run_callbacks(CALLBACK_ID_STEAM_MESSAGES, msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Networking::handle_tcp(Common_Message *msg, struct TCP_Socket &socket)
|
bool Networking::handle_tcp(Common_Message *msg, struct TCP_Socket &socket)
|
||||||
|
|
|
@ -60,6 +60,7 @@ enum Callback_Ids {
|
||||||
CALLBACK_ID_AUTH_TICKET,
|
CALLBACK_ID_AUTH_TICKET,
|
||||||
CALLBACK_ID_FRIEND_MESSAGES,
|
CALLBACK_ID_FRIEND_MESSAGES,
|
||||||
CALLBACK_ID_NETWORKING_SOCKETS,
|
CALLBACK_ID_NETWORKING_SOCKETS,
|
||||||
|
CALLBACK_ID_STEAM_MESSAGES,
|
||||||
|
|
||||||
CALLBACK_IDS_MAX
|
CALLBACK_IDS_MAX
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <cctype>
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <impls/imgui_impl_win32.h>
|
#include <impls/imgui_impl_win32.h>
|
||||||
|
|
||||||
|
@ -98,6 +99,7 @@ Steam_Overlay::Steam_Overlay(Settings* settings, SteamCallResults* callback_resu
|
||||||
overlay_state_changed(false)
|
overlay_state_changed(false)
|
||||||
{
|
{
|
||||||
run_every_runcb->add(&Steam_Overlay::steam_overlay_run_every_runcb, this);
|
run_every_runcb->add(&Steam_Overlay::steam_overlay_run_every_runcb, this);
|
||||||
|
this->network->setCallback(CALLBACK_ID_STEAM_MESSAGES, settings->get_local_steam_id(), &Steam_Overlay::steam_overlay_callback, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Steam_Overlay::~Steam_Overlay()
|
Steam_Overlay::~Steam_Overlay()
|
||||||
|
@ -105,6 +107,12 @@ Steam_Overlay::~Steam_Overlay()
|
||||||
run_every_runcb->remove(&Steam_Overlay::steam_overlay_run_every_runcb, this);
|
run_every_runcb->remove(&Steam_Overlay::steam_overlay_run_every_runcb, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Steam_Overlay::steam_overlay_callback(void* object, Common_Message* msg)
|
||||||
|
{
|
||||||
|
Steam_Overlay* _this = reinterpret_cast<Steam_Overlay*>(object);
|
||||||
|
_this->Callback(msg);
|
||||||
|
}
|
||||||
|
|
||||||
void Steam_Overlay::steam_overlay_run_every_runcb(void* object)
|
void Steam_Overlay::steam_overlay_run_every_runcb(void* object)
|
||||||
{
|
{
|
||||||
Steam_Overlay* _this = reinterpret_cast<Steam_Overlay*>(object);
|
Steam_Overlay* _this = reinterpret_cast<Steam_Overlay*>(object);
|
||||||
|
@ -262,6 +270,7 @@ void Steam_Overlay::FriendConnect(Friend _friend)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||||
friends[_friend].window_state = window_state_none;
|
friends[_friend].window_state = window_state_none;
|
||||||
|
memset(friends[_friend].chat_input, 0, max_chat_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Steam_Overlay::FriendDisconnect(Friend _friend)
|
void Steam_Overlay::FriendDisconnect(Friend _friend)
|
||||||
|
@ -296,13 +305,13 @@ void Steam_Overlay::BuildFriendWindow(Friend const& frd, friend_window_state& st
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool show = true;
|
bool show = true;
|
||||||
ImGui::SetNextWindowSizeConstraints({ 160.0,90.0 }, { 9999.0, 9999.0 });
|
|
||||||
if (ImGui::Begin(frd.name().c_str(), &show))
|
if (ImGui::Begin(frd.name().c_str(), &show))
|
||||||
{
|
{
|
||||||
// Fill this with the chat box and maybe the invitation
|
// Fill this with the chat box and maybe the invitation
|
||||||
if (state.window_state & (window_state_lobby_invite | window_state_rich_invite))
|
if (state.window_state & (window_state_lobby_invite | window_state_rich_invite))
|
||||||
{
|
{
|
||||||
ImGui::LabelText("", "%s invited you to join the game.", frd.name().c_str());
|
ImGui::LabelText("##label", "%s invited you to join the game.", frd.name().c_str());
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Button("Accept"))
|
if (ImGui::Button("Accept"))
|
||||||
{
|
{
|
||||||
|
@ -314,6 +323,30 @@ void Steam_Overlay::BuildFriendWindow(Friend const& frd, friend_window_state& st
|
||||||
state.window_state &= ~(window_state_lobby_invite | window_state_rich_invite);
|
state.window_state &= ~(window_state_lobby_invite | window_state_rich_invite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::PushItemWidth(-1.0f);
|
||||||
|
ImGui::InputTextMultiline("##chat_history", &state.chat_history[0], state.chat_history.length(), { -1.0f, 0 }, ImGuiInputTextFlags_ReadOnly);
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
|
||||||
|
if (ImGui::InputText("##chat_line", state.chat_input, max_chat_len, ImGuiInputTextFlags_EnterReturnsTrue))
|
||||||
|
{
|
||||||
|
if (!(state.window_state & window_state_send_message))
|
||||||
|
{
|
||||||
|
has_friend_action.push(frd);
|
||||||
|
state.window_state |= window_state_send_message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
if (ImGui::Button("Send"))
|
||||||
|
{
|
||||||
|
if (!(state.window_state & window_state_send_message))
|
||||||
|
{
|
||||||
|
has_friend_action.push(frd);
|
||||||
|
state.window_state |= window_state_send_message;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// User closed the friend window
|
// User closed the friend window
|
||||||
if (!show)
|
if (!show)
|
||||||
|
@ -335,18 +368,17 @@ void Steam_Overlay::OverlayProc( int width, int height )
|
||||||
ImGui::SetNextWindowSize({ static_cast<float>(width),
|
ImGui::SetNextWindowSize({ static_cast<float>(width),
|
||||||
static_cast<float>(height) });
|
static_cast<float>(height) });
|
||||||
|
|
||||||
bool open_overlay = show_overlay;
|
if (ImGui::Begin("SteamOverlay", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus))
|
||||||
if (ImGui::Begin("SteamOverlay", &open_overlay, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus))
|
|
||||||
{
|
{
|
||||||
ImGui::LabelText("", "Username: %s(%llu) playing %u",
|
ImGui::LabelText("##label", "Username: %s(%llu) playing %u",
|
||||||
settings->get_local_name(),
|
settings->get_local_name(),
|
||||||
settings->get_local_steam_id().ConvertToUint64(),
|
settings->get_local_steam_id().ConvertToUint64(),
|
||||||
settings->get_local_game_id().AppID());
|
settings->get_local_game_id().AppID());
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|
||||||
ImGui::LabelText("", "Friends");
|
ImGui::LabelText("##label", "Friends");
|
||||||
ImGui::ListBoxHeader("", friend_size);
|
ImGui::ListBoxHeader("##label", friend_size);
|
||||||
std::for_each(friends.begin(), friends.end(), [this]( auto& i)
|
std::for_each(friends.begin(), friends.end(), [this]( auto& i)
|
||||||
{
|
{
|
||||||
ImGui::PushID(i.first.id());
|
ImGui::PushID(i.first.id());
|
||||||
|
@ -372,11 +404,25 @@ void Steam_Overlay::OverlayProc( int width, int height )
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
ShowOverlay(open_overlay);
|
|
||||||
|
|
||||||
//ImGui::ShowDemoWindow();
|
//ImGui::ShowDemoWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Steam_Overlay::Callback(Common_Message *msg)
|
||||||
|
{
|
||||||
|
if (msg->has_steam_messages())
|
||||||
|
{
|
||||||
|
Friend frd;
|
||||||
|
frd.set_id(msg->source_id());
|
||||||
|
auto friend_info = friends.find(frd);
|
||||||
|
if (friend_info != friends.end())
|
||||||
|
{
|
||||||
|
Steam_Messages const& steam_message = msg->steam_messages();
|
||||||
|
// Change color to cyan for friend
|
||||||
|
friend_info->second.chat_history.append("\x1", 1).append("00FFFFFF", 8).append(steam_message.message()).append("\n", 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Steam_Overlay::RunCallbacks()
|
void Steam_Overlay::RunCallbacks()
|
||||||
{
|
{
|
||||||
if (overlay_state_changed)
|
if (overlay_state_changed)
|
||||||
|
@ -397,6 +443,31 @@ void Steam_Overlay::RunCallbacks()
|
||||||
if (friend_info != friends.end())
|
if (friend_info != friends.end())
|
||||||
{
|
{
|
||||||
uint64 friend_id = friend_info->first.id();
|
uint64 friend_id = friend_info->first.id();
|
||||||
|
// The user clicken on "Send"
|
||||||
|
if (friend_info->second.window_state & window_state_send_message)
|
||||||
|
{
|
||||||
|
char* input = friend_info->second.chat_input;
|
||||||
|
char* end_input = input + strlen(input);
|
||||||
|
char* printable_char = std::find_if(input, end_input, [](char c) {
|
||||||
|
return std::isgraph(c);
|
||||||
|
});
|
||||||
|
if (printable_char != end_input)
|
||||||
|
{
|
||||||
|
// Handle chat send
|
||||||
|
Common_Message msg;
|
||||||
|
Steam_Messages* steam_messages = new Steam_Messages;
|
||||||
|
steam_messages->set_type(Steam_Messages::FRIEND_CHAT);
|
||||||
|
steam_messages->set_message(friend_info->second.chat_input);
|
||||||
|
msg.set_allocated_steam_messages(steam_messages);
|
||||||
|
msg.set_source_id(settings->get_local_steam_id().ConvertToUint64());
|
||||||
|
msg.set_dest_id(friend_id);
|
||||||
|
network->sendTo(&msg, true);
|
||||||
|
|
||||||
|
friend_info->second.chat_history.append("\x1", 1).append("00FF00FF", 8).append(input).append("\n", 1);
|
||||||
|
}
|
||||||
|
*input = 0; // Reset the input field
|
||||||
|
friend_info->second.window_state &= ~window_state_send_message;
|
||||||
|
}
|
||||||
// The user clicked on "Invite"
|
// The user clicked on "Invite"
|
||||||
if (friend_info->second.window_state & window_state_invite)
|
if (friend_info->second.window_state & window_state_invite)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
|
static constexpr size_t max_chat_len = 768;
|
||||||
|
|
||||||
enum window_state
|
enum window_state
|
||||||
{
|
{
|
||||||
window_state_none = 0,
|
window_state_none = 0,
|
||||||
|
@ -13,17 +15,20 @@ enum window_state
|
||||||
window_state_invite = 1<<1,
|
window_state_invite = 1<<1,
|
||||||
window_state_join = 1<<2,
|
window_state_join = 1<<2,
|
||||||
window_state_lobby_invite = 1<<3,
|
window_state_lobby_invite = 1<<3,
|
||||||
window_state_rich_invite = 1<<4
|
window_state_rich_invite = 1<<4,
|
||||||
|
window_state_send_message = 1<<5,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct friend_window_state
|
struct friend_window_state
|
||||||
{
|
{
|
||||||
uint8 window_state;
|
uint8 window_state;
|
||||||
union
|
union // The invitation (if any)
|
||||||
{
|
{
|
||||||
uint64 lobbyId;
|
uint64 lobbyId;
|
||||||
char connect[k_cchMaxRichPresenceValueLength];
|
char connect[k_cchMaxRichPresenceValueLength];
|
||||||
};
|
};
|
||||||
|
std::string chat_history;
|
||||||
|
char chat_input[max_chat_len];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Friend_Less
|
struct Friend_Less
|
||||||
|
@ -70,6 +75,9 @@ class Steam_Overlay
|
||||||
static LRESULT WINAPI MyDispatchMessageW(const MSG* lpMsg);
|
static LRESULT WINAPI MyDispatchMessageW(const MSG* lpMsg);
|
||||||
|
|
||||||
static void steam_overlay_run_every_runcb(void* object);
|
static void steam_overlay_run_every_runcb(void* object);
|
||||||
|
static void steam_overlay_callback(void* object, Common_Message* msg);
|
||||||
|
|
||||||
|
void Callback(Common_Message* msg);
|
||||||
void RunCallbacks();
|
void RunCallbacks();
|
||||||
|
|
||||||
// Right click on friend
|
// Right click on friend
|
||||||
|
|
Loading…
Reference in New Issue