Merge pull request #1718 from LordSk/feature/broadcast

Server broadcast
This commit is contained in:
oy 2018-11-26 19:25:41 +01:00 committed by GitHub
commit a8e77ef535
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 437 additions and 25 deletions

View file

@ -243,6 +243,10 @@ Messages = [
NetString("m_pMessage"),
]),
NetMessage("Sv_Broadcast", [
NetString("m_pMessage"),
]),
NetMessage("Sv_Chat", [
NetIntRange("m_Mode", 0, 'NUM_CHATS-1'),
NetIntRange("m_ClientID", -1, 'MAX_CLIENTS-1'),

View file

@ -498,6 +498,7 @@ public:
pCursor->m_LineCount = 1;
pCursor->m_LineWidth = -1;
pCursor->m_Flags = Flags;
pCursor->m_GlyphCount = 0;
pCursor->m_CharCount = 0;
}
@ -672,7 +673,7 @@ public:
{
// word can't be fitted in one line, cut it
CTextCursor Cutter = *pCursor;
Cutter.m_CharCount = 0;
Cutter.m_GlyphCount = 0;
Cutter.m_X = DrawX;
Cutter.m_Y = DrawY;
Cutter.m_Flags &= ~TEXTFLAG_RENDER;
@ -680,7 +681,7 @@ public:
TextDeferredRenderEx(&Cutter, (const char *)pCurrent, Wlen, aQuadChar, QuadCharMaxCount,
pQuadCharCount, pFontTexture);
Wlen = Cutter.m_CharCount;
Wlen = Cutter.m_GlyphCount;
NewLine = 1;
if(Wlen <= 3) // if we can't place 3 chars of the word on this line, take the next
@ -699,6 +700,7 @@ public:
int NextCharacter = str_utf8_decode(&pTmp);
while(pCurrent < pBatchEnd)
{
pCursor->m_CharCount += pTmp-pCurrent;
int Character = NextCharacter;
pCurrent = pTmp;
NextCharacter = str_utf8_decode(&pTmp);
@ -742,7 +744,7 @@ public:
}
DrawX += Advance*Size;
pCursor->m_CharCount++;
pCursor->m_GlyphCount++;
}
}
@ -861,14 +863,14 @@ public:
{
// word can't be fitted in one line, cut it
CTextCursor Cutter = *pCursor;
Cutter.m_CharCount = 0;
Cutter.m_GlyphCount = 0;
Cutter.m_X = DrawX;
Cutter.m_Y = DrawY;
Cutter.m_Flags &= ~TEXTFLAG_RENDER;
Cutter.m_Flags |= TEXTFLAG_STOP_AT_END;
TextEx(&Cutter, (const char *)pCurrent, Wlen);
Wlen = Cutter.m_CharCount;
Wlen = Cutter.m_GlyphCount;
NewLine = 1;
if(Wlen <= 3) // if we can't place 3 chars of the word on this line, take the next
@ -887,6 +889,7 @@ public:
int NextCharacter = str_utf8_decode(&pTmp);
while(pCurrent < pBatchEnd)
{
pCursor->m_CharCount += pTmp-pCurrent;
int Character = NextCharacter;
pCurrent = pTmp;
NextCharacter = str_utf8_decode(&pTmp);
@ -922,7 +925,7 @@ public:
}
DrawX += Advance*Size;
pCursor->m_CharCount++;
pCursor->m_GlyphCount++;
}
}

View file

@ -24,6 +24,9 @@ MACRO_CONFIG_INT(ClAutoDemoMax, cl_auto_demo_max, 10, 0, 1000, CFGFLAG_SAVE|CFGF
MACRO_CONFIG_INT(ClAutoScreenshot, cl_auto_screenshot, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Automatically take game over screenshot")
MACRO_CONFIG_INT(ClAutoScreenshotMax, cl_auto_screenshot_max, 10, 0, 1000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Maximum number of automatically created screenshots (0 = no limit)")
MACRO_CONFIG_INT(ClShowServerBroadcast, cl_show_server_broadcast, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Show server broadcast")
MACRO_CONFIG_INT(ClColoredBroadcast, cl_colored_broadcast, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Enable colored server broadcasts")
MACRO_CONFIG_STR(BrFilterString, br_filter_string, 25, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "Server browser filtering string")
MACRO_CONFIG_INT(BrSort, br_sort, 0, 0, 256, CFGFLAG_SAVE|CFGFLAG_CLIENT, "")

View file

@ -20,6 +20,7 @@ class CTextCursor
public:
int m_Flags;
int m_LineCount;
int m_GlyphCount;
int m_CharCount;
int m_MaxLines;

View file

@ -8,11 +8,186 @@
#include <game/client/gameclient.h>
#include <game/client/components/motd.h>
#include <game/client/components/scoreboard.h>
#include "broadcast.h"
#include "chat.h"
#include "scoreboard.h"
#include "motd.h"
#define BROADCAST_FONTSIZE_BIG 11.0f
#define BROADCAST_FONTSIZE_SMALL 6.5f
inline bool IsCharANum(char c)
{
return c >= '0' && c <= '9';
}
inline int WordLengthBack(const char *pText, int MaxChars)
{
int s = 0;
while(MaxChars--)
{
if((*pText == '\n' || *pText == '\t' || *pText == ' '))
return s;
pText--;
s++;
}
return 0;
}
inline bool IsCharWhitespace(char c)
{
return c == '\n' || c == '\t' || c == ' ';
}
void CBroadcast::RenderServerBroadcast()
{
if(!g_Config.m_ClShowServerBroadcast || m_pClient->m_MuteServerBroadcast)
return;
const bool ColoredBroadcastEnabled = g_Config.m_ClColoredBroadcast;
const float Height = 300;
const float Width = Height*Graphics()->ScreenAspect();
const float DisplayDuration = 10.0f;
const float DisplayStartFade = 9.0f;
const float DeltaTime = Client()->LocalTime() - m_SrvBroadcastReceivedTime;
if(m_aSrvBroadcastMsg[0] == 0 || DeltaTime > DisplayDuration)
return;
if(m_pClient->m_pChat->IsActive())
return;
const float Fade = 1.0f - max(0.0f, (DeltaTime - DisplayStartFade) / (DisplayDuration - DisplayStartFade));
CUIRect ScreenRect = {0, 0, Width, Height};
CUIRect BcView = ScreenRect;
BcView.x += Width * 0.25f;
BcView.y += Height * 0.8f;
BcView.w *= 0.5f;
BcView.h *= 0.2f;
vec4 ColorTop(0, 0, 0, 0);
vec4 ColorBot(0, 0, 0, 0.4f * Fade);
CUIRect BgRect;
BcView.HSplitBottom(10.0f, 0, &BgRect);
BcView.HSplitBottom(8.0f, &BcView, 0);
// draw bottom bar
const float CornerWidth = 12.0f;
BgRect.VMargin(CornerWidth, &BgRect);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
IGraphics::CFreeformItem LeftCorner(
BgRect.x - CornerWidth, BgRect.y + BgRect.h,
BgRect.x, BgRect.y,
BgRect.x, BgRect.y + BgRect.h,
BgRect.x, BgRect.y + BgRect.h
);
IGraphics::CColorVertex aColorVert[4] = {
IGraphics::CColorVertex(0, 0,0,0, 0.0f),
IGraphics::CColorVertex(1, 0,0,0, 0.0f),
IGraphics::CColorVertex(2, 0,0,0, 0.4f * Fade),
IGraphics::CColorVertex(3, 0,0,0, 0.4f * Fade)};
Graphics()->SetColorVertex(aColorVert, 4);
Graphics()->QuadsDrawFreeform(&LeftCorner, 1);
IGraphics::CFreeformItem RightCorner(
BgRect.x+BgRect.w + CornerWidth, BgRect.y + BgRect.h,
BgRect.x+BgRect.w, BgRect.y,
BgRect.x+BgRect.w, BgRect.y + BgRect.h,
BgRect.x+BgRect.w, BgRect.y + BgRect.h
);
Graphics()->SetColorVertex(aColorVert, 4);
Graphics()->QuadsDrawFreeform(&RightCorner, 1);
Graphics()->QuadsEnd();
RenderTools()->DrawUIRect4(&BgRect, ColorTop, ColorTop,
ColorBot, ColorBot, 0, 0);
BcView.VMargin(5.0f, &BcView);
BcView.HSplitBottom(2.0f, &BcView, 0);
// draw lines
const float FontSize = m_SrvBroadcastFontSize;
const int LineCount = m_SrvBroadcastLineCount;
const char* pBroadcastMsg = m_aSrvBroadcastMsg;
CTextCursor Cursor;
TextRender()->TextColor(1, 1, 1, 1);
TextRender()->TextOutlineColor(0, 0, 0, 0.3f);
float y = BcView.y + BcView.h - LineCount * FontSize;
for(int l = 0; l < LineCount; l++)
{
const CBcLineInfo& Line = m_aSrvBroadcastLines[l];
TextRender()->SetCursor(&Cursor, BcView.x + (BcView.w - Line.m_Width) * 0.5f, y,
FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END);
Cursor.m_LineWidth = BcView.w;
// draw colored text
if(ColoredBroadcastEnabled)
{
int DrawnStrLen = 0;
int ThisCharPos = Line.m_pStrStart - pBroadcastMsg;
while(DrawnStrLen < Line.m_StrLen)
{
int StartColorID = -1;
int ColorStrLen = -1;
// find color
for(int j = 0; j < m_SrvBroadcastColorCount; j++)
{
if((ThisCharPos+DrawnStrLen) >= m_aSrvBroadcastColorList[j].m_CharPos)
{
StartColorID = j;
}
else if(StartColorID >= 0)
{
ColorStrLen = m_aSrvBroadcastColorList[j].m_CharPos -
max(m_aSrvBroadcastColorList[StartColorID].m_CharPos, ThisCharPos);
break;
}
}
dbg_assert(StartColorID >= 0, "This should not be -1, color not found");
if(ColorStrLen < 0)
ColorStrLen = Line.m_StrLen-DrawnStrLen;
ColorStrLen = min(ColorStrLen, Line.m_StrLen-DrawnStrLen);
const CBcColor& TextColor = m_aSrvBroadcastColorList[StartColorID];
float r = TextColor.m_R/255.f;
float g = TextColor.m_G/255.f;
float b = TextColor.m_B/255.f;
float AvgLum = 0.2126*r + 0.7152*g + 0.0722*b;
if(AvgLum < 0.25f)
TextRender()->TextOutlineColor(1, 1, 1, 0.6f);
else
TextRender()->TextOutlineColor(0, 0, 0, 0.3f);
TextRender()->TextColor(r, g, b, Fade);
TextRender()->TextEx(&Cursor, Line.m_pStrStart+DrawnStrLen, ColorStrLen);
DrawnStrLen += ColorStrLen;
}
}
else
{
TextRender()->TextEx(&Cursor, Line.m_pStrStart, Line.m_StrLen);
}
y += FontSize;
}
TextRender()->TextColor(1, 1, 1, 1);
TextRender()->TextOutlineColor(0, 0, 0, 0.3f);
}
CBroadcast::CBroadcast()
{
@ -27,7 +202,7 @@ void CBroadcast::DoBroadcast(const char *pText)
Cursor.m_LineWidth = 300*Graphics()->ScreenAspect();
TextRender()->TextEx(&Cursor, m_aBroadcastText, -1);
m_BroadcastRenderOffset = 150*Graphics()->ScreenAspect()-Cursor.m_X/2;
m_BroadcastTime = time_get()+time_freq()*10;
m_BroadcastTime = Client()->LocalTime() + 10.0f;
}
void CBroadcast::OnReset()
@ -35,6 +210,158 @@ void CBroadcast::OnReset()
m_BroadcastTime = 0;
}
void CBroadcast::OnMessage(int MsgType, void* pRawMsg)
{
// process server broadcast message
if(MsgType == NETMSGTYPE_SV_BROADCAST && g_Config.m_ClShowServerBroadcast &&
!m_pClient->m_MuteServerBroadcast)
{
CNetMsg_Sv_Broadcast *pMsg = (CNetMsg_Sv_Broadcast *)pRawMsg;
// new broadcast message
int RcvMsgLen = str_length(pMsg->m_pMessage);
mem_zero(m_aSrvBroadcastMsg, sizeof(m_aSrvBroadcastMsg));
m_aSrvBroadcastMsgLen = 0;
m_SrvBroadcastReceivedTime = Client()->LocalTime();
const CBcColor White = { 255, 255, 255, 0 };
m_aSrvBroadcastColorList[0] = White;
m_SrvBroadcastColorCount = 1;
CBcLineInfo UserLines[MAX_BROADCAST_LINES];
int UserLineCount = 0;
int LastUserLineStartPoint = 0;
// parse colors
for(int i = 0; i < RcvMsgLen; i++)
{
const char* c = pMsg->m_pMessage + i;
const char* pTmp = c;
int CharUtf8 = str_utf8_decode(&pTmp);
const int Utf8Len = pTmp-c;
if(*c == CharUtf8 && *c == '^')
{
if(i+3 < RcvMsgLen && IsCharANum(c[1]) && IsCharANum(c[2]) && IsCharANum(c[3]))
{
u8 r = (c[1] - '0') * 24 + 39;
u8 g = (c[2] - '0') * 24 + 39;
u8 b = (c[3] - '0') * 24 + 39;
CBcColor Color = { r, g, b, m_aSrvBroadcastMsgLen };
if(m_SrvBroadcastColorCount < MAX_BROADCAST_COLORS)
m_aSrvBroadcastColorList[m_SrvBroadcastColorCount++] = Color;
i += 3;
continue;
}
}
if(*c == CharUtf8 && *c == '\\')
{
if(i+1 < RcvMsgLen && c[1] == 'n' && UserLineCount < MAX_BROADCAST_LINES)
{
CBcLineInfo Line = { m_aSrvBroadcastMsg+LastUserLineStartPoint,
m_aSrvBroadcastMsgLen-LastUserLineStartPoint, 0 };
if(Line.m_StrLen > 0)
UserLines[UserLineCount++] = Line;
LastUserLineStartPoint = m_aSrvBroadcastMsgLen;
i++;
continue;
}
}
if(m_aSrvBroadcastMsgLen+Utf8Len < MAX_BROADCAST_MSG_LENGTH)
m_aSrvBroadcastMsg[m_aSrvBroadcastMsgLen++] = *c;
}
// last user defined line
if(LastUserLineStartPoint > 0 && UserLineCount < 3)
{
CBcLineInfo Line = { m_aSrvBroadcastMsg+LastUserLineStartPoint,
m_aSrvBroadcastMsgLen-LastUserLineStartPoint, 0 };
if(Line.m_StrLen > 0)
UserLines[UserLineCount++] = Line;
}
const float Height = 300;
const float Width = Height*Graphics()->ScreenAspect();
const float LineMaxWidth = Width * 0.5f - 10.0f;
// process boradcast message
const char* pBroadcastMsg = m_aSrvBroadcastMsg;
const int MsgLen = m_aSrvBroadcastMsgLen;
CTextCursor Cursor;
Graphics()->MapScreen(0, 0, Width, Height);
// one line == big font
// 2+ lines == small font
m_SrvBroadcastLineCount = 0;
float FontSize = BROADCAST_FONTSIZE_BIG;
if(UserLineCount <= 1) // auto mode
{
TextRender()->SetCursor(&Cursor, 0, 0, FontSize, 0);
Cursor.m_LineWidth = LineMaxWidth;
TextRender()->TextEx(&Cursor, pBroadcastMsg, MsgLen);
// can't fit on one line, reduce size
if(Cursor.m_LineCount > 1)
FontSize = BROADCAST_FONTSIZE_SMALL; // smaller font
// make lines
int CurCharCount = 0;
while(CurCharCount < MsgLen && m_SrvBroadcastLineCount < MAX_BROADCAST_LINES)
{
const char* RemainingMsg = pBroadcastMsg + CurCharCount;
TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END);
Cursor.m_LineWidth = LineMaxWidth;
TextRender()->TextEx(&Cursor, RemainingMsg, -1);
int StrLen = Cursor.m_CharCount;
// don't cut words
if(CurCharCount + StrLen < MsgLen)
{
const int WorldLen = WordLengthBack(RemainingMsg + StrLen, StrLen);
if(WorldLen > 0 && WorldLen < StrLen)
{
StrLen -= WorldLen;
TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END);
Cursor.m_LineWidth = LineMaxWidth;
TextRender()->TextEx(&Cursor, RemainingMsg, StrLen);
}
}
const float TextWidth = Cursor.m_X-Cursor.m_StartX;
CBcLineInfo Line = { RemainingMsg, StrLen, TextWidth };
m_aSrvBroadcastLines[m_SrvBroadcastLineCount++] = Line;
CurCharCount += StrLen;
}
}
else // user defined lines mode
{
FontSize = BROADCAST_FONTSIZE_SMALL;
for(int i = 0; i < UserLineCount && m_SrvBroadcastLineCount < MAX_BROADCAST_LINES; i++)
{
TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END);
Cursor.m_LineWidth = LineMaxWidth;
TextRender()->TextEx(&Cursor, UserLines[i].m_pStrStart, UserLines[i].m_StrLen);
const float TextWidth = Cursor.m_X-Cursor.m_StartX;
const int StrLen = Cursor.m_CharCount;
CBcLineInfo Line = { UserLines[i].m_pStrStart, StrLen, TextWidth };
m_aSrvBroadcastLines[m_SrvBroadcastLineCount++] = Line;
}
}
m_SrvBroadcastFontSize = FontSize;
}
}
void CBroadcast::OnRender()
{
if(m_pClient->m_pScoreboard->Active() || m_pClient->m_pMotd->IsActive())
@ -42,12 +369,16 @@ void CBroadcast::OnRender()
Graphics()->MapScreen(0, 0, 300*Graphics()->ScreenAspect(), 300);
if(time_get() < m_BroadcastTime)
// client broadcast
if(Client()->LocalTime() < m_BroadcastTime)
{
CTextCursor Cursor;
TextRender()->SetCursor(&Cursor, m_BroadcastRenderOffset, 40.0f, 12.0f, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END);
Cursor.m_LineWidth = 300*Graphics()->ScreenAspect()-m_BroadcastRenderOffset;
TextRender()->TextEx(&Cursor, m_aBroadcastText, -1);
}
// server broadcast
RenderServerBroadcast();
}

View file

@ -7,15 +7,48 @@
class CBroadcast : public CComponent
{
char m_aBroadcastText[128];
int64 m_BroadcastTime;
float m_BroadcastTime;
float m_BroadcastRenderOffset;
// server broadcast
typedef unsigned char u8;
struct CBcColor
{
u8 m_R, m_G, m_B;
int m_CharPos;
};
struct CBcLineInfo
{
const char* m_pStrStart;
int m_StrLen;
float m_Width;
};
enum {
MAX_BROADCAST_COLORS = 128,
MAX_BROADCAST_MSG_LENGTH = 127,
MAX_BROADCAST_LINES = 3,
};
CBcColor m_aSrvBroadcastColorList[MAX_BROADCAST_COLORS];
CBcLineInfo m_aSrvBroadcastLines[MAX_BROADCAST_LINES];
char m_aSrvBroadcastMsg[MAX_BROADCAST_MSG_LENGTH+1];
int m_aSrvBroadcastMsgLen;
int m_SrvBroadcastColorCount;
int m_SrvBroadcastLineCount;
float m_SrvBroadcastReceivedTime;
float m_SrvBroadcastFontSize;
void RenderServerBroadcast();
public:
CBroadcast();
void DoBroadcast(const char *pText);
virtual void OnReset();
virtual void OnMessage(int MsgType, void *pRawMsg);
virtual void OnRender();
};

View file

@ -618,7 +618,8 @@ void CHud::RenderHealthAndAmmo(const CNetObj_Character *pCharacter)
void CHud::RenderSpectatorHud()
{
// draw the box
CUIRect Rect = {m_Width-180.0f, m_Height-15.0f, 180.0f, 15.0f};
const float Width = m_Width * 0.25f - 2.0f;
CUIRect Rect = {m_Width-Width, m_Height-15.0f, Width, 15.0f};
RenderTools()->DrawUIRect(&Rect, vec4(0.0f, 0.0f, 0.0f, 0.4f), CUI::CORNER_TL, 5.0f);
// draw the text
@ -629,7 +630,7 @@ void CHud::RenderSpectatorHud()
char aBuf[128];
CTextCursor Cursor;
TextRender()->SetCursor(&Cursor, m_Width-174.0f, m_Height-13.0f, 8.0f, TEXTFLAG_RENDER);
TextRender()->SetCursor(&Cursor, m_Width-Width+6.0f, m_Height-13.0f, 8.0f, TEXTFLAG_RENDER);
str_format(aBuf, sizeof(aBuf), "%s: ", Localize("Spectate"));
TextRender()->TextEx(&Cursor, aBuf, -1);

View file

@ -363,6 +363,17 @@ void CMenus::RenderServerInfo(CUIRect MainView)
ServerBrowser()->AddFavorite(&CurrentServerInfo);
}
{
CUIRect Button;
ServerInfo.HSplitBottom(20.0f, &ServerInfo, &Button);
static int s_MuteBroadcast = 0;
if(DoButton_CheckBox(&s_MuteBroadcast, Localize("Mute broadcasts"),
m_pClient->m_MuteServerBroadcast, &Button))
{
m_pClient->m_MuteServerBroadcast ^= 1;
}
}
// gameinfo
GameInfo.VSplitLeft(1.0f, 0, &GameInfo);
RenderTools()->DrawUIRect(&GameInfo, vec4(0.0, 0.0, 0.0, 0.25f), CUI::CORNER_ALL, 5.0f);

View file

@ -1019,6 +1019,13 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView)
g_Config.m_ClFilterchat = (g_Config.m_ClFilterchat + 1) % 3;
}
GameRight.HSplitTop(Spacing, 0, &GameRight);
GameRight.HSplitTop(ButtonHeight, &Button, &GameRight);
static int s_EnableColoredBroadcasts = 0;
if(DoButton_CheckBox(&s_EnableColoredBroadcasts, Localize("Enable colored server broadcasts"),
g_Config.m_ClColoredBroadcast, &Button))
g_Config.m_ClColoredBroadcast ^= 1;
// render client menu
Client.HSplitTop(ButtonHeight, &Label, &Client);
Label.y += 2.0f;

View file

@ -369,6 +369,7 @@ void CGameClient::OnReset()
m_DemoSpecMode = SPEC_FREEVIEW;
m_DemoSpecID = -1;
m_Tuning = CTuningParams();
m_MuteServerBroadcast = false;
}

View file

@ -194,6 +194,7 @@ public:
CClientData m_aClients[MAX_CLIENTS];
int m_LocalClientID;
int m_TeamCooldownTick;
bool m_MuteServerBroadcast;
struct CGameInfo
{

View file

@ -241,6 +241,13 @@ void CGameContext::SendChat(int ChatterClientID, int Mode, int To, const char *p
}
}
void CGameContext::SendBroadcast(const char* pText, int ClientID)
{
CNetMsg_Sv_Broadcast Msg;
Msg.m_pMessage = pText;
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, ClientID);
}
void CGameContext::SendEmoticon(int ClientID, int Emoticon)
{
CNetMsg_Sv_Emoticon Msg;
@ -1094,6 +1101,12 @@ void CGameContext::ConSay(IConsole::IResult *pResult, void *pUserData)
pSelf->SendChat(-1, CHAT_ALL, -1, pResult->GetString(0));
}
void CGameContext::ConBroadcast(IConsole::IResult* pResult, void* pUserData)
{
CGameContext *pSelf = (CGameContext *)pUserData;
pSelf->SendBroadcast(pResult->GetString(0), -1);
}
void CGameContext::ConSetTeam(IConsole::IResult *pResult, void *pUserData)
{
CGameContext *pSelf = (CGameContext *)pUserData;
@ -1381,6 +1394,7 @@ void CGameContext::OnConsoleInit()
Console()->Register("change_map", "?r", CFGFLAG_SERVER|CFGFLAG_STORE, ConChangeMap, this, "Change map");
Console()->Register("restart", "?i", CFGFLAG_SERVER|CFGFLAG_STORE, ConRestart, this, "Restart in x seconds (0 = abort)");
Console()->Register("say", "r", CFGFLAG_SERVER, ConSay, this, "Say in chat");
Console()->Register("broadcast", "r", CFGFLAG_SERVER, ConBroadcast, this, "Broadcast message");
Console()->Register("set_team", "ii?i", CFGFLAG_SERVER, ConSetTeam, this, "Set team of player to team");
Console()->Register("set_team_all", "i", CFGFLAG_SERVER, ConSetTeamAll, this, "Set team of all players to team");
Console()->Register("swap_teams", "", CFGFLAG_SERVER, ConSwapTeams, this, "Swap the current teams");

View file

@ -49,6 +49,7 @@ class CGameContext : public IGameServer
static void ConChangeMap(IConsole::IResult *pResult, void *pUserData);
static void ConRestart(IConsole::IResult *pResult, void *pUserData);
static void ConSay(IConsole::IResult *pResult, void *pUserData);
static void ConBroadcast(IConsole::IResult *pResult, void *pUserData);
static void ConSetTeam(IConsole::IResult *pResult, void *pUserData);
static void ConSetTeamAll(IConsole::IResult *pResult, void *pUserData);
static void ConSwapTeams(IConsole::IResult *pResult, void *pUserData);
@ -132,6 +133,7 @@ public:
// network
void SendChat(int ChatterClientID, int Mode, int To, const char *pText);
void SendBroadcast(const char *pText, int ClientID);
void SendEmoticon(int ClientID, int Emoticon);
void SendWeaponPickup(int ClientID, int Weapon);
void SendMotd(int ClientID);