merged whispering system by cinaera

This commit is contained in:
oy 2017-12-11 10:52:54 +01:00
parent 2503dfdaec
commit f548838356
6 changed files with 126 additions and 90 deletions

View file

@ -4,6 +4,7 @@ Pickups = Enum("PICKUP", ["HEALTH", "ARMOR", "GRENADE", "SHOTGUN", "LASER", "NIN
Emotes = Enum("EMOTE", ["NORMAL", "PAIN", "HAPPY", "SURPRISE", "ANGRY", "BLINK"])
Emoticons = Enum("EMOTICON", ["OOP", "EXCLAMATION", "HEARTS", "DROP", "DOTDOT", "MUSIC", "SORRY", "GHOST", "SUSHI", "SPLATTEE", "DEVILTEE", "ZOMG", "ZZZ", "WTF", "EYES", "QUESTION"])
Votes = Enum("VOTE", ["UNKNOWN", "START_OP", "START_KICK", "START_SPEC", "END_ABORT", "END_PASS", "END_FAIL"])
ChatModes = Enum("CHAT", ["NONE", "ALL", "TEAM", "WHISPER"])
PlayerFlags = Flags("PLAYERFLAG", ["ADMIN", "CHATTING", "SCOREBOARD", "READY", "DEAD", "WATCHING"])
GameFlags = Flags("GAMEFLAG", ["TEAMS", "FLAGS", "SURVIVAL"])
@ -55,6 +56,7 @@ Enums = [
Emotes,
Emoticons,
Votes,
ChatModes,
GameMsgIDs,
]
@ -240,7 +242,7 @@ Messages = [
]),
NetMessage("Sv_Chat", [
NetIntRange("m_Team", 'TEAM_SPECTATORS', 'TEAM_BLUE'),
NetIntRange("m_Mode", 0, 'NUM_CHATS-1'),
NetIntRange("m_ClientID", -1, 'MAX_CLIENTS-1'),
NetStringStrict("m_pMessage"),
]),
@ -352,7 +354,8 @@ Messages = [
### Client messages
NetMessage("Cl_Say", [
NetBool("m_Team"),
NetIntRange("m_Mode", 0, 'NUM_CHATS-1'),
NetIntRange("m_Target", -1, 'MAX_CLIENTS-1'),
NetStringStrict("m_pMessage"),
]),

View file

@ -34,7 +34,7 @@ void CChat::OnReset()
m_aLines[i].m_aName[0] = 0;
}
m_Mode = MODE_NONE;
m_Mode = CHAT_NONE;
m_ReverseCompletion = false;
m_Show = false;
m_InputUpdate = false;
@ -61,7 +61,7 @@ void CChat::OnStateChange(int NewState, int OldState)
{
if(OldState <= IClient::STATE_CONNECTING)
{
m_Mode = MODE_NONE;
m_Mode = CHAT_NONE;
for(int i = 0; i < MAX_LINES; i++)
m_aLines[i].m_Time = 0;
m_CurrentLine = 0;
@ -70,23 +70,50 @@ void CChat::OnStateChange(int NewState, int OldState)
void CChat::ConSay(IConsole::IResult *pResult, void *pUserData)
{
((CChat*)pUserData)->Say(0, pResult->GetString(0));
((CChat*)pUserData)->Say(CHAT_ALL, pResult->GetString(0));
}
void CChat::ConSayTeam(IConsole::IResult *pResult, void *pUserData)
{
((CChat*)pUserData)->Say(1, pResult->GetString(0));
((CChat*)pUserData)->Say(CHAT_TEAM, pResult->GetString(0));
}
void CChat::ConWhisper(IConsole::IResult *pResult, void *pUserData)
{
CChat *pChat = (CChat *)pUserData;
int Target = pResult->GetInteger(0);
if(Target < 0 || Target >= MAX_CLIENTS || !pChat->m_pClient->m_aClients[Target].m_Active || pChat->m_pClient->m_LocalClientID == Target)
pChat->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "console", "please enter a valid ClientID");
else
{
pChat->m_WhisperTarget = Target;
pChat->Say(CHAT_WHISPER, pResult->GetString(1));
}
}
void CChat::ConChat(IConsole::IResult *pResult, void *pUserData)
{
CChat *pChat = (CChat *)pUserData;
const char *pMode = pResult->GetString(0);
if(str_comp(pMode, "all") == 0)
((CChat*)pUserData)->EnableMode(0);
pChat->EnableMode(CHAT_ALL);
else if(str_comp(pMode, "team") == 0)
((CChat*)pUserData)->EnableMode(1);
pChat->EnableMode(CHAT_TEAM);
else if(str_comp(pMode, "whisper") == 0)
{
int Target = pResult->GetInteger(1);
if(Target < 0 || Target >= MAX_CLIENTS || !pChat->m_pClient->m_aClients[Target].m_Active || pChat->m_pClient->m_LocalClientID == Target)
pChat->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "console", "please enter a valid ClientID");
else
{
pChat->m_WhisperTarget = Target;
pChat->EnableMode(CHAT_WHISPER);
}
}
else
((CChat*)pUserData)->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "console", "expected all or team as mode");
((CChat*)pUserData)->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "console", "expected all, team or whisper as mode");
}
void CChat::ConShowChat(IConsole::IResult *pResult, void *pUserData)
@ -98,18 +125,19 @@ void CChat::OnConsoleInit()
{
Console()->Register("say", "r", CFGFLAG_CLIENT, ConSay, this, "Say in chat");
Console()->Register("say_team", "r", CFGFLAG_CLIENT, ConSayTeam, this, "Say in team chat");
Console()->Register("chat", "s", CFGFLAG_CLIENT, ConChat, this, "Enable chat with all/team mode");
Console()->Register("whisper", "ir", CFGFLAG_CLIENT, ConWhisper, this, "Whisper to a client in chat");
Console()->Register("chat", "s?i", CFGFLAG_CLIENT, ConChat, this, "Enable chat with all/team/whisper mode");
Console()->Register("+show_chat", "", CFGFLAG_CLIENT, ConShowChat, this, "Show chat");
}
bool CChat::OnInput(IInput::CEvent Event)
{
if(m_Mode == MODE_NONE)
if(m_Mode == CHAT_NONE)
return false;
if(Event.m_Flags&IInput::FLAG_PRESS && Event.m_Key == KEY_ESCAPE)
{
m_Mode = MODE_NONE;
m_Mode = CHAT_NONE;
m_pClient->OnRelease();
}
else if(Event.m_Flags&IInput::FLAG_PRESS && (Event.m_Key == KEY_RETURN || Event.m_Key == KEY_KP_ENTER))
@ -120,7 +148,7 @@ bool CChat::OnInput(IInput::CEvent Event)
if(m_LastChatSend+time_freq() < time_get())
{
Say(m_Mode == MODE_ALL ? 0 : 1, m_Input.GetString());
Say(m_Mode, m_Input.GetString());
AddEntry = true;
}
else if(m_PendingChatCounter < 3)
@ -132,12 +160,12 @@ bool CChat::OnInput(IInput::CEvent Event)
if(AddEntry)
{
CHistoryEntry *pEntry = m_History.Allocate(sizeof(CHistoryEntry)+m_Input.GetLength());
pEntry->m_Team = m_Mode == MODE_ALL ? 0 : 1;
pEntry->m_Mode = m_Mode;
mem_copy(pEntry->m_aText, m_Input.GetString(), m_Input.GetLength()+1);
}
}
m_pHistoryEntry = 0x0;
m_Mode = MODE_NONE;
m_Mode = CHAT_NONE;
m_pClient->OnRelease();
}
if(Event.m_Flags&IInput::FLAG_PRESS && Event.m_Key == KEY_TAB)
@ -281,18 +309,14 @@ bool CChat::OnInput(IInput::CEvent Event)
}
void CChat::EnableMode(int Team)
void CChat::EnableMode(int Mode)
{
if(Client()->State() == IClient::STATE_DEMOPLAYBACK)
return;
if(m_Mode == MODE_NONE)
if(m_Mode == CHAT_NONE)
{
if(Team)
m_Mode = MODE_TEAM;
else
m_Mode = MODE_ALL;
m_Mode = Mode;
m_Input.Clear();
Input()->Clear();
m_CompletionChosen = -1;
@ -304,11 +328,11 @@ void CChat::OnMessage(int MsgType, void *pRawMsg)
if(MsgType == NETMSGTYPE_SV_CHAT)
{
CNetMsg_Sv_Chat *pMsg = (CNetMsg_Sv_Chat *)pRawMsg;
AddLine(pMsg->m_ClientID, pMsg->m_Team, pMsg->m_pMessage);
AddLine(pMsg->m_ClientID, pMsg->m_Mode, pMsg->m_pMessage);
}
}
void CChat::AddLine(int ClientID, int Team, const char *pLine)
void CChat::AddLine(int ClientID, int Mode, const char *pLine)
{
if(*pLine == 0 || (ClientID != -1 && (!g_Config.m_ClShowsocial || m_pClient->m_aClients[ClientID].m_aName[0] == '\0' || // unknown client
m_pClient->m_aClients[ClientID].m_ChatIgnore ||
@ -364,7 +388,7 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine)
m_aLines[m_CurrentLine].m_YOffset[0] = -1.0f;
m_aLines[m_CurrentLine].m_YOffset[1] = -1.0f;
m_aLines[m_CurrentLine].m_ClientID = ClientID;
m_aLines[m_CurrentLine].m_Team = Team;
m_aLines[m_CurrentLine].m_Mode = Mode;
m_aLines[m_CurrentLine].m_NameColor = -2;
// check for highlighted name
@ -376,7 +400,8 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine)
Highlighted = true;
m_CompletionFav = ClientID;
}
m_aLines[m_CurrentLine].m_Highlighted = Highlighted;
m_aLines[m_CurrentLine].m_Highlighted = Highlighted || Mode == CHAT_WHISPER;
if(ClientID == -1) // server message
{
@ -401,8 +426,15 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine)
}
char aBuf[1024];
char aBufMode[32];
if(Mode == CHAT_WHISPER)
str_copy(aBufMode, "whisper", sizeof(aBufMode));
else if(Mode == CHAT_TEAM)
str_copy(aBufMode, "teamchat", sizeof(aBufMode));
else
str_copy(aBufMode, "chat", sizeof(aBufMode));
str_format(aBuf, sizeof(aBuf), "%s%s", m_aLines[m_CurrentLine].m_aName, m_aLines[m_CurrentLine].m_aText);
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, m_aLines[m_CurrentLine].m_Team?"teamchat":"chat", aBuf, Highlighted);
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, aBufMode, aBuf, Highlighted);
}
// play sound
@ -443,7 +475,7 @@ void CChat::OnRender()
{
if(i == 0)
{
Say(pEntry->m_Team, pEntry->m_aText);
Say(pEntry->m_Mode, pEntry->m_aText);
break;
}
}
@ -458,7 +490,7 @@ void CChat::OnRender()
Graphics()->MapScreen(0.0f, 0.0f, Width, 300.0f);
float x = 5.0f;
float y = 300.0f-20.0f;
if(m_Mode != MODE_NONE)
if(m_Mode != CHAT_NONE)
{
// render chat input
CTextCursor Cursor;
@ -466,13 +498,17 @@ void CChat::OnRender()
Cursor.m_LineWidth = Width-190.0f;
Cursor.m_MaxLines = 2;
if(m_Mode == MODE_ALL)
TextRender()->TextEx(&Cursor, Localize("All"), -1);
else if(m_Mode == MODE_TEAM)
TextRender()->TextEx(&Cursor, Localize("Team"), -1);
char aBuf[32];
if(m_Mode == CHAT_ALL)
str_copy(aBuf, Localize("All"), sizeof(aBuf));
else if(m_Mode == CHAT_TEAM)
str_copy(aBuf, Localize("Team"), sizeof(aBuf));
else if(m_Mode == CHAT_WHISPER)
str_format(aBuf, sizeof(aBuf), "%s %s", Localize("To"), m_pClient->m_aClients[m_WhisperTarget].m_aName);
else
TextRender()->TextEx(&Cursor, Localize("Chat"), -1);
str_copy(aBuf, Localize("Chat"), sizeof(aBuf));
TextRender()->TextEx(&Cursor, aBuf, -1);
TextRender()->TextEx(&Cursor, ": ", -1);
// check if the visible text has to be moved
@ -548,7 +584,7 @@ void CChat::OnRender()
// render name
if(m_aLines[r].m_ClientID == -1)
TextRender()->TextColor(1.0f, 1.0f, 0.5f, Blend); // system
else if(m_aLines[r].m_Team)
else if(m_aLines[r].m_Mode == CHAT_TEAM)
TextRender()->TextColor(0.45f, 0.9f, 0.45f, Blend); // team message
else if(m_aLines[r].m_NameColor == TEAM_RED)
TextRender()->TextColor(1.0f, 0.5f, 0.5f, Blend); // red
@ -566,7 +602,7 @@ void CChat::OnRender()
TextRender()->TextColor(1.0f, 1.0f, 0.5f, Blend); // system
else if(m_aLines[r].m_Highlighted)
TextRender()->TextColor(1.0f, 0.5f, 0.5f, Blend); // highlighted
else if(m_aLines[r].m_Team)
else if(m_aLines[r].m_Mode == CHAT_TEAM)
TextRender()->TextColor(0.65f, 1.0f, 0.65f, Blend); // team message
else
TextRender()->TextColor(1.0f, 1.0f, 1.0f, Blend);
@ -577,13 +613,14 @@ void CChat::OnRender()
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
}
void CChat::Say(int Team, const char *pLine)
void CChat::Say(int Mode, const char *pLine)
{
m_LastChatSend = time_get();
// send chat message
CNetMsg_Cl_Say Msg;
Msg.m_Team = Team;
Msg.m_Mode = Mode;
Msg.m_Target = Mode==CHAT_WHISPER ? m_WhisperTarget : -1;
Msg.m_pMessage = pLine;
Client()->SendPackMsg(&Msg, MSGFLAG_VITAL);
}

View file

@ -20,7 +20,7 @@ class CChat : public CComponent
int64 m_Time;
float m_YOffset[2];
int m_ClientID;
int m_Team;
int m_Mode;
int m_NameColor;
char m_aName[64];
char m_aText[512];
@ -33,10 +33,6 @@ class CChat : public CComponent
// chat
enum
{
MODE_NONE=0,
MODE_ALL,
MODE_TEAM,
CHAT_SERVER=0,
CHAT_HIGHLIGHT,
CHAT_CLIENT,
@ -44,6 +40,7 @@ class CChat : public CComponent
};
int m_Mode;
int m_WhisperTarget;
bool m_Show;
bool m_InputUpdate;
int m_ChatStringOffset;
@ -57,7 +54,7 @@ class CChat : public CComponent
struct CHistoryEntry
{
int m_Team;
int m_Mode;
char m_aText[1];
};
CHistoryEntry *m_pHistoryEntry;
@ -68,13 +65,14 @@ class CChat : public CComponent
static void ConSay(IConsole::IResult *pResult, void *pUserData);
static void ConSayTeam(IConsole::IResult *pResult, void *pUserData);
static void ConWhisper(IConsole::IResult *pResult, void *pUserData);
static void ConChat(IConsole::IResult *pResult, void *pUserData);
static void ConShowChat(IConsole::IResult *pResult, void *pUserData);
public:
CChat();
bool IsActive() const { return m_Mode != MODE_NONE; }
bool IsActive() const { return m_Mode != CHAT_NONE; }
void AddLine(int ClientID, int Team, const char *pLine);

View file

@ -895,7 +895,8 @@ void CGameClient::OnNewSnapshot()
aMessage[MsgLen] = 0;
CNetMsg_Cl_Say Msg;
Msg.m_Team = random_int()&1;
Msg.m_Mode = random_int()&1;
Msg.m_Target = -1;
Msg.m_pMessage = aMessage;
Client()->SendPackMsg(&Msg, MSGFLAG_VITAL);
}

View file

@ -190,51 +190,52 @@ void CGameContext::CreateSound(vec2 Pos, int Sound, int Mask)
}
}
void CGameContext::SendChatTarget(int To, const char *pText)
{
CNetMsg_Sv_Chat Msg;
Msg.m_Team = 0;
Msg.m_ClientID = -1;
Msg.m_pMessage = pText;
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, To);
}
void CGameContext::SendChat(int ChatterClientID, int Team, const char *pText)
void CGameContext::SendChat(int ChatterClientID, int Mode, int To, const char *pText)
{
char aBuf[256];
if(ChatterClientID >= 0 && ChatterClientID < MAX_CLIENTS)
str_format(aBuf, sizeof(aBuf), "%d:%d:%s: %s", ChatterClientID, Team, Server()->ClientName(ChatterClientID), pText);
str_format(aBuf, sizeof(aBuf), "%d:%d:%s: %s", ChatterClientID, Mode, Server()->ClientName(ChatterClientID), pText);
else
str_format(aBuf, sizeof(aBuf), "*** %s", pText);
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, Team!=CHAT_ALL?"teamchat":"chat", aBuf);
if(Team == CHAT_ALL)
{
CNetMsg_Sv_Chat Msg;
Msg.m_Team = 0;
Msg.m_ClientID = ChatterClientID;
Msg.m_pMessage = pText;
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, -1);
}
char aBufMode[32];
if(Mode == CHAT_WHISPER)
str_copy(aBufMode, "whisper", sizeof(aBufMode));
else if(Mode == CHAT_TEAM)
str_copy(aBufMode, "teamchat", sizeof(aBufMode));
else
{
CNetMsg_Sv_Chat Msg;
Msg.m_Team = 1;
Msg.m_ClientID = ChatterClientID;
Msg.m_pMessage = pText;
str_copy(aBufMode, "chat", sizeof(aBufMode));
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, aBufMode, aBuf);
CNetMsg_Sv_Chat Msg;
Msg.m_Mode = Mode;
Msg.m_ClientID = ChatterClientID;
Msg.m_pMessage = pText;
if(Mode == CHAT_ALL)
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, -1);
else if(Mode == CHAT_TEAM)
{
// pack one for the recording only
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL|MSGFLAG_NOSEND, -1);
To = m_apPlayers[ChatterClientID]->GetTeam();
// send to the clients
for(int i = 0; i < MAX_CLIENTS; i++)
{
if(m_apPlayers[i] && m_apPlayers[i]->GetTeam() == Team)
if(m_apPlayers[i] && m_apPlayers[i]->GetTeam() == To)
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL|MSGFLAG_NORECORD, i);
}
}
else // Mode == CHAT_WHISPER
{
// send to the clients
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, ChatterClientID);
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, To);
}
}
void CGameContext::SendEmoticon(int ClientID, int Emoticon)
@ -714,7 +715,6 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
return;
CNetMsg_Cl_Say *pMsg = (CNetMsg_Cl_Say *)pRawMsg;
int Team = pMsg->m_Team ? pPlayer->GetTeam() : CGameContext::CHAT_ALL;
// trim right and set maximum length to 128 utf8-characters
int Length = 0;
@ -751,13 +751,20 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
pPlayer->m_LastChat = Server()->Tick();
// don't allow spectators to disturb players during a running game in tournament mode
int Mode = pMsg->m_Mode;
if((g_Config.m_SvTournamentMode == 2) &&
pPlayer->GetTeam() == TEAM_SPECTATORS &&
m_pController->IsGameRunning() &&
!Server()->IsAuthed(ClientID))
Team = TEAM_SPECTATORS;
{
if(Mode != CHAT_WHISPER)
Mode = CHAT_TEAM;
else if(m_apPlayers[pMsg->m_Target] && m_apPlayers[pMsg->m_Target]->GetTeam() != TEAM_SPECTATORS)
Mode = CHAT_NONE;
}
SendChat(ClientID, Team, pMsg->m_pMessage);
if(Mode != CHAT_NONE)
SendChat(ClientID, Mode, pMsg->m_Target, pMsg->m_pMessage);
}
else if(MsgID == NETMSGTYPE_CL_CALLVOTE)
{
@ -1078,7 +1085,7 @@ void CGameContext::ConRestart(IConsole::IResult *pResult, void *pUserData)
void CGameContext::ConSay(IConsole::IResult *pResult, void *pUserData)
{
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->SendChat(-1, CGameContext::CHAT_ALL, pResult->GetString(0));
pSelf->SendChat(-1, CHAT_ALL, -1, pResult->GetString(0));
}
void CGameContext::ConSetTeam(IConsole::IResult *pResult, void *pUserData)

View file

@ -130,18 +130,8 @@ public:
void CreateDeath(vec2 Pos, int Who);
void CreateSound(vec2 Pos, int Sound, int Mask=-1);
enum
{
CHAT_ALL=-2,
CHAT_SPEC=-1,
CHAT_RED=0,
CHAT_BLUE=1
};
// network
void SendChatTarget(int To, const char *pText);
void SendChat(int ClientID, int Team, const char *pText);
void SendChat(int ChatterClientID, int Mode, int To, const char *pText);
void SendEmoticon(int ClientID, int Emoticon);
void SendWeaponPickup(int ClientID, int Weapon);
void SendMotd(int ClientID);