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
|
||||
{
|
||||
ImU32 color_bkp = col;
|
||||
|
||||
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.
|
||||
|
||||
|
@ -2871,6 +2873,34 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
|
|||
|
||||
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)
|
||||
{
|
||||
// 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 {
|
||||
uint64 source_id = 1;
|
||||
uint64 dest_id = 2;
|
||||
|
@ -200,6 +211,7 @@ message Common_Message {
|
|||
Friend_Messages friend_messages = 11;
|
||||
Network_Old network_old = 12;
|
||||
Networking_Sockets networking_sockets = 13;
|
||||
Steam_Messages steam_messages = 14;
|
||||
}
|
||||
|
||||
uint32 source_ip = 128;
|
||||
|
|
|
@ -533,6 +533,11 @@ void Networking::do_callbacks_message(Common_Message *msg)
|
|||
PRINT_DEBUG("has_networking_sockets\n");
|
||||
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)
|
||||
|
|
|
@ -60,6 +60,7 @@ enum Callback_Ids {
|
|||
CALLBACK_ID_AUTH_TICKET,
|
||||
CALLBACK_ID_FRIEND_MESSAGES,
|
||||
CALLBACK_ID_NETWORKING_SOCKETS,
|
||||
CALLBACK_ID_STEAM_MESSAGES,
|
||||
|
||||
CALLBACK_IDS_MAX
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <thread>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <cctype>
|
||||
#include <imgui.h>
|
||||
#include <impls/imgui_impl_win32.h>
|
||||
|
||||
|
@ -98,6 +99,7 @@ Steam_Overlay::Steam_Overlay(Settings* settings, SteamCallResults* callback_resu
|
|||
overlay_state_changed(false)
|
||||
{
|
||||
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()
|
||||
|
@ -105,6 +107,12 @@ Steam_Overlay::~Steam_Overlay()
|
|||
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)
|
||||
{
|
||||
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);
|
||||
friends[_friend].window_state = window_state_none;
|
||||
memset(friends[_friend].chat_input, 0, max_chat_len);
|
||||
}
|
||||
|
||||
void Steam_Overlay::FriendDisconnect(Friend _friend)
|
||||
|
@ -296,13 +305,13 @@ void Steam_Overlay::BuildFriendWindow(Friend const& frd, friend_window_state& st
|
|||
return;
|
||||
|
||||
bool show = true;
|
||||
ImGui::SetNextWindowSizeConstraints({ 160.0,90.0 }, { 9999.0, 9999.0 });
|
||||
|
||||
if (ImGui::Begin(frd.name().c_str(), &show))
|
||||
{
|
||||
// Fill this with the chat box and maybe the invitation
|
||||
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();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
if (!show)
|
||||
|
@ -335,18 +368,17 @@ void Steam_Overlay::OverlayProc( int width, int height )
|
|||
ImGui::SetNextWindowSize({ static_cast<float>(width),
|
||||
static_cast<float>(height) });
|
||||
|
||||
bool open_overlay = show_overlay;
|
||||
if (ImGui::Begin("SteamOverlay", &open_overlay, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus))
|
||||
if (ImGui::Begin("SteamOverlay", nullptr, 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_steam_id().ConvertToUint64(),
|
||||
settings->get_local_game_id().AppID());
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
ImGui::LabelText("", "Friends");
|
||||
ImGui::ListBoxHeader("", friend_size);
|
||||
ImGui::LabelText("##label", "Friends");
|
||||
ImGui::ListBoxHeader("##label", friend_size);
|
||||
std::for_each(friends.begin(), friends.end(), [this]( auto& i)
|
||||
{
|
||||
ImGui::PushID(i.first.id());
|
||||
|
@ -372,11 +404,25 @@ void Steam_Overlay::OverlayProc( int width, int height )
|
|||
}
|
||||
ImGui::End();
|
||||
|
||||
ShowOverlay(open_overlay);
|
||||
|
||||
//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()
|
||||
{
|
||||
if (overlay_state_changed)
|
||||
|
@ -397,6 +443,31 @@ void Steam_Overlay::RunCallbacks()
|
|||
if (friend_info != friends.end())
|
||||
{
|
||||
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"
|
||||
if (friend_info->second.window_state & window_state_invite)
|
||||
{
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include <map>
|
||||
#include <queue>
|
||||
|
||||
static constexpr size_t max_chat_len = 768;
|
||||
|
||||
enum window_state
|
||||
{
|
||||
window_state_none = 0,
|
||||
|
@ -13,17 +15,20 @@ enum window_state
|
|||
window_state_invite = 1<<1,
|
||||
window_state_join = 1<<2,
|
||||
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
|
||||
{
|
||||
uint8 window_state;
|
||||
union
|
||||
union // The invitation (if any)
|
||||
{
|
||||
uint64 lobbyId;
|
||||
char connect[k_cchMaxRichPresenceValueLength];
|
||||
};
|
||||
std::string chat_history;
|
||||
char chat_input[max_chat_len];
|
||||
};
|
||||
|
||||
struct Friend_Less
|
||||
|
@ -70,6 +75,9 @@ class Steam_Overlay
|
|||
static LRESULT WINAPI MyDispatchMessageW(const MSG* lpMsg);
|
||||
|
||||
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();
|
||||
|
||||
// Right click on friend
|
||||
|
|
Loading…
Reference in New Issue