Add functions all about handling Message of the Day server info. Adds the motd
console command, as well as motdfile
.
This commit is contained in:
parent
6c0256782f
commit
338e89c06a
12 changed files with 233 additions and 7 deletions
|
@ -374,6 +374,9 @@ Cmd_Parse(string sCMD)
|
|||
case "player_geomtest":
|
||||
CMD_player_geomtest();
|
||||
break;
|
||||
case "motd":
|
||||
print(MOTD_GetTextBody());
|
||||
break;
|
||||
|
||||
/* XR binds, engine binds them currently */
|
||||
case "+attack_left":
|
||||
|
@ -455,6 +458,9 @@ Cmd_Init(void)
|
|||
registercommand("vote");
|
||||
registercommand("callvote");
|
||||
|
||||
/* motd */
|
||||
registercommand("motd");
|
||||
|
||||
/* hud weapon selection system */
|
||||
registercommand("slot1");
|
||||
registercommand("slot2");
|
||||
|
|
|
@ -76,6 +76,7 @@ CSQC_Init(float apilevel, string enginename, float engineversion)
|
|||
Decals_Init();
|
||||
Way_Init();
|
||||
Materials_Init();
|
||||
MOTD_Init();
|
||||
|
||||
/* let the menu know we're a multi or a singleplayer game */
|
||||
if (serverkeyfloat("sv_playerslots") == 1)
|
||||
|
|
|
@ -104,6 +104,16 @@ void Font_DrawRText_RGBA(vector vecOrigin, string strText, vector col, float a,
|
|||
@param iAlignFlags sets how the text may be aligned. */
|
||||
void Font_DrawField(vector vecOrigin, vector vecSize, string strText, font_s fnt, alignflags_t iAlignFlags);
|
||||
|
||||
/** Draws a textfield with line wrapping at a custom text height.
|
||||
|
||||
@param vecOrigin is the absolute starting position.
|
||||
@param vecSize is the total area in pixels that the field takes up on the screen.
|
||||
@param iTextHeight is the desired text height in pixels.
|
||||
@param strText is the text to be drawn onto the screen.
|
||||
@param fnt is the font to be used for rendering the text.
|
||||
@param iAlignFlags sets how the text may be aligned. */
|
||||
void Font_DrawFieldAtHeight(vector vecOrigin, vector vecSize, int iTextHeight, string strText, font_s fnt, alignflags_t iAlignFlags);
|
||||
|
||||
/** Converts a normalized RGB color vector to a hex color string.
|
||||
|
||||
@param vecColor is the normalized input color. E.g. [1.0f, 0.0f, 0.0f]
|
||||
|
|
|
@ -162,6 +162,17 @@ Font_DrawField(vector vecOrigin, vector vecSize, string strText, font_s fnt, ali
|
|||
drawfontscale = [1,1,0];
|
||||
}
|
||||
|
||||
void
|
||||
Font_DrawFieldAtHeight(vector vecOrigin, vector vecSize, int iTextHeight, string strText, font_s fnt, alignflags_t iAlignFlags)
|
||||
{
|
||||
drawfont = (float)fnt.iID;
|
||||
drawfontscale[0] = (float)iTextHeight / 8;
|
||||
drawfontscale[1] = (float)iTextHeight / 8;
|
||||
drawtextfield(vecOrigin, vecSize, (float)iAlignFlags, strText);
|
||||
drawfont = 0;
|
||||
drawfontscale = [1,1,0];
|
||||
}
|
||||
|
||||
string
|
||||
Font_RGBtoHex(vector vecColor)
|
||||
{
|
||||
|
|
|
@ -374,6 +374,7 @@ initents(void)
|
|||
{
|
||||
/* sound shader init */
|
||||
Materials_Init();
|
||||
MOTD_Init();
|
||||
PMove_Init();
|
||||
|
||||
/* TODO: turn these effects into sound shaders */
|
||||
|
|
|
@ -89,6 +89,7 @@ string __fullspawndata;
|
|||
#include "decalgroups.h"
|
||||
#include "colors.h"
|
||||
#include "weapons.h"
|
||||
#include "motd.h"
|
||||
|
||||
#define BSPVER_PREREL 28
|
||||
#define BSPVER_Q1 29
|
||||
|
|
|
@ -33,6 +33,7 @@ sentences.qc
|
|||
NSSpraylogo.qc
|
||||
util.qc
|
||||
weapons.qc
|
||||
motd.qc
|
||||
|
||||
../xr/include.src
|
||||
#endlist
|
||||
|
|
40
src/shared/motd.h
Normal file
40
src/shared/motd.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef SERVER
|
||||
var string autocvar_motdfile = "motd.txt";
|
||||
#define MOTD_FILE autocvar_motdfile
|
||||
|
||||
/** Hard-limit to how many lines are allowed within a message of the day. */
|
||||
#define MOTD_LINES 32
|
||||
|
||||
/** Called on the server to load the default 'message of the day' file. */
|
||||
void MOTD_LoadDefault(void);
|
||||
|
||||
/** Called on the server to load a specific 'message of the day' file. */
|
||||
void MOT_LoadFromFile(string);
|
||||
#endif
|
||||
|
||||
/** Called by CSQC_Init() on the client game and by initents() on the server game to
|
||||
set up a networked 'message of the day'. */
|
||||
void MOTD_Init(void);
|
||||
|
||||
#ifdef CLIENT
|
||||
/** Returns the full text body of the 'message of the day' that is on the server. Can be retrieved by clients via the `motd` console command. */
|
||||
string MOTD_GetTextBody(void);
|
||||
/** Returns how many individual lines are present in the message of the day. */
|
||||
int MOTD_GetLineCount(void);
|
||||
#endif
|
102
src/shared/motd.qc
Normal file
102
src/shared/motd.qc
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef CLIENT
|
||||
static string g_motd_body;
|
||||
static int g_motd_lines;
|
||||
#endif
|
||||
|
||||
void
|
||||
MOTD_Init(void)
|
||||
{
|
||||
#ifdef SERVER
|
||||
/* wipe the slate clean */
|
||||
for (int i = 0; i < MOTD_LINES; i++) {
|
||||
localcmd(sprintf("serverinfo motdline%i \"\"\n", i));
|
||||
}
|
||||
localcmd("serverinfo motdlines \"\"\n");
|
||||
#endif
|
||||
#ifdef CLIENT
|
||||
int motdLines = stoi(serverkey("motdlines"));
|
||||
g_motd_body = "";
|
||||
|
||||
for (int i = 0; i < motdLines; i++) {
|
||||
string line = serverkey(sprintf("motdline%i", i));
|
||||
if (line != "/") {
|
||||
g_motd_body = strcat(g_motd_body, line, "\n");
|
||||
} else {
|
||||
g_motd_body = strcat(g_motd_body, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
g_motd_lines = motdLines;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SERVER
|
||||
void
|
||||
MOTD_LoadDefault(void)
|
||||
{
|
||||
MOT_LoadFromFile(MOTD_FILE);
|
||||
}
|
||||
|
||||
void
|
||||
MOT_LoadFromFile(string fileName)
|
||||
{
|
||||
/* init motd */
|
||||
string tempString;
|
||||
int motdLines = 0;
|
||||
|
||||
filestream fileMotd = fopen(fileName, FILE_READ);
|
||||
|
||||
/* now read in the new motd */
|
||||
if (fileMotd != -1) {
|
||||
for (int i = 0; i < MOTD_LINES; i++) {
|
||||
tempString = fgets(fileMotd);
|
||||
if not (tempString) {
|
||||
break;
|
||||
} else if (tempString == __NULL__) {
|
||||
localcmd(sprintf("serverinfo motdline%i /\n", motdLines));
|
||||
} else {
|
||||
localcmd(sprintf("serverinfo motdline%i %S\n", motdLines, tempString));
|
||||
}
|
||||
|
||||
motdLines++;
|
||||
}
|
||||
localcmd(sprintf("serverinfo motdlines \"%i\"\n", motdLines));
|
||||
fclose(fileMotd);
|
||||
} else {
|
||||
NSLog("Failed to parse motd from %S", MOTD_FILE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT
|
||||
string
|
||||
MOTD_GetTextBody(void)
|
||||
{
|
||||
if (g_motd_lines > 0i)
|
||||
return g_motd_body;
|
||||
else
|
||||
return "Server advertises no message of the day.";
|
||||
}
|
||||
|
||||
int
|
||||
MOTD_GetLineCount(void)
|
||||
{
|
||||
return g_motd_lines;
|
||||
}
|
||||
#endif
|
|
@ -89,6 +89,7 @@ VGUIButton::SetTitle(string strName)
|
|||
|
||||
m_strTitle = strName;
|
||||
m_strTitleActive = sprintf("^3%s", m_strTitle);
|
||||
m_strTitle = sprintf("%s%s", Font_RGBtoHex(UI_MAINCOLOR), strName);
|
||||
drawfont = g_fntDefault.iID;
|
||||
|
||||
newsize[0] = stringwidth(m_strTitle, TRUE, [g_fntDefault.iScaleX, g_fntDefault.iScaleY]) + 16;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/** A VGUI label/text field. */
|
||||
class VGUILabel:VGUIWidget
|
||||
{
|
||||
public:
|
||||
|
@ -24,15 +25,19 @@ public:
|
|||
virtual void Draw(void);
|
||||
virtual bool Input(float, float, float, float);
|
||||
virtual void Spawned(void);
|
||||
virtual void SetTextSize(int);
|
||||
|
||||
private:
|
||||
string m_strTitle;
|
||||
int m_labelFlags;
|
||||
int m_textSize;
|
||||
};
|
||||
|
||||
void
|
||||
VGUILabel::VGUILabel(void)
|
||||
{
|
||||
m_strTitle = __NULL__;
|
||||
m_labelFlags = AF_TOP | AF_LEFT;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -56,11 +61,29 @@ VGUILabel::SetTitle (string strName)
|
|||
SetSize([2 + stringwidth(m_strTitle, TRUE, [g_fntDefault.iScaleX, g_fntDefault.iScaleY]), 16]);
|
||||
}
|
||||
|
||||
void
|
||||
VGUILabel::SetTextSize(int val)
|
||||
{
|
||||
m_textSize = val;
|
||||
}
|
||||
|
||||
void
|
||||
VGUILabel::Draw(void)
|
||||
{
|
||||
if (m_strTitle) {
|
||||
Font_DrawField(m_parent.m_vecOrigin + m_vecOrigin, m_vecSize, m_strTitle, g_fntDefault, 0);
|
||||
vector pos;
|
||||
vector size;
|
||||
|
||||
pos = m_parent.m_vecOrigin + m_vecOrigin;
|
||||
size = m_vecSize;
|
||||
drawsetcliparea(pos[0], pos[1], size[0], size[1]);
|
||||
|
||||
if (!m_textSize)
|
||||
Font_DrawField(pos, size, m_strTitle, g_fntDefault, m_labelFlags);
|
||||
else
|
||||
Font_DrawFieldAtHeight(pos, size, m_textSize, m_strTitle, g_fntDefault, m_labelFlags);
|
||||
|
||||
drawresetcliparea();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,9 +18,18 @@ enumflags
|
|||
{
|
||||
WINDOW_DRAGGING,
|
||||
WINDOW_RESIZING,
|
||||
WINDOW_CANRESIZE
|
||||
};
|
||||
|
||||
typedef enumflags
|
||||
{
|
||||
VGUIWindowBorderless,
|
||||
VGUIWindowTitled,
|
||||
VGUIWindowClosable,
|
||||
VGUIWindowMiniaturizable,
|
||||
VGUIWindowResizeable,
|
||||
VGUIWindowMovable,
|
||||
} vguiWindowStyle_t;
|
||||
|
||||
/** Top-most window class in VGUILib */
|
||||
class VGUIWindow:VGUIWidget
|
||||
{
|
||||
|
@ -42,6 +51,9 @@ public:
|
|||
/** Called when the window has been repositioned by the user. */
|
||||
nonvirtual void CallOnMove(void(void) vFunc);
|
||||
|
||||
/** Sets the style mask of the specified window. */
|
||||
nonvirtual void SetStyleMask(vguiWindowStyle_t);
|
||||
|
||||
/* overrides */
|
||||
virtual void Draw(void);
|
||||
virtual void SizeChanged(vector, vector);
|
||||
|
@ -54,6 +66,7 @@ private:
|
|||
vector m_vecDragOffset;
|
||||
string m_strTitle;
|
||||
string m_strIcon;
|
||||
vguiWindowStyle_t m_styleMask;
|
||||
|
||||
VGUIButton m_btnClose;
|
||||
|
||||
|
@ -66,6 +79,21 @@ VGUIWindow::VGUIWindow(void)
|
|||
{
|
||||
m_vecColor = UI_MAINCOLOR;
|
||||
m_flAlpha = 1.0f;
|
||||
m_styleMask = VGUIWindowMovable |
|
||||
VGUIWindowTitled |
|
||||
VGUIWindowClosable |
|
||||
VGUIWindowMiniaturizable |
|
||||
VGUIWindowResizeable;
|
||||
}
|
||||
|
||||
void
|
||||
VGUIWindow::SetStyleMask(vguiWindowStyle_t val)
|
||||
{
|
||||
if (!(val & VGUIWindowClosable)) {
|
||||
m_btnClose.Hide();
|
||||
}
|
||||
|
||||
m_styleMask = val;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -140,7 +168,7 @@ void VGUIWindow::Draw(void)
|
|||
drawfill(m_vecOrigin + [0, 1], [1, m_vecSize[1] - 2], m_vecColor, 1.0f);
|
||||
drawfill(m_vecOrigin + [m_vecSize[0] - 1, 1], [1, m_vecSize[1] - 2], m_vecColor, 1.0f);
|
||||
|
||||
if (m_iFlags & WINDOW_CANRESIZE) {
|
||||
if (m_styleMask & VGUIWindowResizeable) {
|
||||
drawpic(m_vecOrigin + m_vecSize - [16,16], "textures/ui/steam/icon_resizer", [16,16], m_vecColor, 1.0f, 0);
|
||||
}
|
||||
#else
|
||||
|
@ -150,11 +178,12 @@ void VGUIWindow::Draw(void)
|
|||
drawfill(m_vecOrigin + [0, 1], [1, m_vecSize[1] - 2], [1,1,1], 0.5f);
|
||||
drawfill(m_vecOrigin + [m_vecSize[0] - 1, 1], [1, m_vecSize[1] - 2], [0,0,0], 0.5f);
|
||||
|
||||
if (m_iFlags & WINDOW_CANRESIZE) {
|
||||
if (m_styleMask & VGUIWindowResizeable) {
|
||||
drawpic(m_vecOrigin + m_vecSize - [16,16], "textures/ui/steam/icon_resizer", [16,16], m_vecColor, 1.0f, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_styleMask & VGUIWindowTitled)
|
||||
if (m_strTitle) {
|
||||
if (m_strIcon) {
|
||||
Font_DrawText(m_vecOrigin + [26, 8], m_strTitle, g_fntDefault);
|
||||
|
@ -163,7 +192,7 @@ void VGUIWindow::Draw(void)
|
|||
Font_DrawText(m_vecOrigin + [8, 8], m_strTitle, g_fntDefault);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef UI_DEVELOPER
|
||||
if (m_iFlags & WINDOW_DRAGGING) {
|
||||
Font_DrawText([8, video_res[1] - 18], sprintf("Window Position: %d, %d\n", m_vecOrigin[0], m_vecOrigin[1]), g_fntDefault);
|
||||
|
@ -180,9 +209,9 @@ bool VGUIWindow::Input (float flEVType, float flKey, float flChar, float flDevID
|
|||
|
||||
if (flEVType == IE_KEYDOWN) {
|
||||
if (flKey == K_MOUSE1) {
|
||||
if (m_iFlags & WINDOW_CANRESIZE && Util_MouseAbove(g_vecMousePos, m_vecOrigin + (m_vecSize - [16,16]), [16,16])) {
|
||||
if (m_styleMask & VGUIWindowResizeable && Util_MouseAbove(g_vecMousePos, m_vecOrigin + (m_vecSize - [16,16]), [16,16])) {
|
||||
m_iFlags |= WINDOW_RESIZING;
|
||||
} else if (Util_MouseAbove(g_vecMousePos, m_vecOrigin, [m_vecSize[0] - 32, 16])) {
|
||||
} else if (m_styleMask & VGUIWindowMovable && Util_MouseAbove(g_vecMousePos, m_vecOrigin, [m_vecSize[0] - 32, 16])) {
|
||||
m_iFlags |= WINDOW_DRAGGING;
|
||||
m_vecDragOffset = m_vecOrigin - g_vecMousePos;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue