mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-05-10 19:01:50 +00:00
Merge branch 'server-name-sanitize' into 'master'
Sanitize server name/contact, fully support caret codes Closes #1008 See merge request KartKrew/Kart!1906
This commit is contained in:
commit
74eee5e718
5 changed files with 212 additions and 78 deletions
|
|
@ -161,6 +161,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
|
||||||
k_credits.cpp
|
k_credits.cpp
|
||||||
music.cpp
|
music.cpp
|
||||||
music_manager.cpp
|
music_manager.cpp
|
||||||
|
sanitize.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(SRB2_CONFIG_ENABLE_WEBM_MOVIES)
|
if(SRB2_CONFIG_ENABLE_WEBM_MOVIES)
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@
|
||||||
#include "k_zvote.h"
|
#include "k_zvote.h"
|
||||||
#include "music.h"
|
#include "music.h"
|
||||||
#include "k_bans.h"
|
#include "k_bans.h"
|
||||||
|
#include "sanitize.h"
|
||||||
|
|
||||||
// cl loading screen
|
// cl loading screen
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
|
|
@ -1001,70 +1002,6 @@ static boolean CL_SendKey(void)
|
||||||
return HSendPacket(servernode, false, 0, sizeof (clientkey_pak) );
|
return HSendPacket(servernode, false, 0, sizeof (clientkey_pak) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
CopyCaretColors (char *p, const char *s, int n)
|
|
||||||
{
|
|
||||||
char *t;
|
|
||||||
int m;
|
|
||||||
int c;
|
|
||||||
if (!n)
|
|
||||||
return;
|
|
||||||
while (( t = strchr(s, '^') ))
|
|
||||||
{
|
|
||||||
m = ( t - s );
|
|
||||||
|
|
||||||
if (m >= n)
|
|
||||||
{
|
|
||||||
memcpy(p, s, n);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
memcpy(p, s, m);
|
|
||||||
|
|
||||||
p += m;
|
|
||||||
n -= m;
|
|
||||||
s += m;
|
|
||||||
|
|
||||||
if (!n)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (s[1])
|
|
||||||
{
|
|
||||||
c = toupper(s[1]);
|
|
||||||
if (isdigit(c))
|
|
||||||
c = 0x80 + ( c - '0' );
|
|
||||||
else if (c >= 'A' && c <= 'F')
|
|
||||||
c = 0x80 + ( c - 'A' );
|
|
||||||
else
|
|
||||||
c = 0;
|
|
||||||
|
|
||||||
if (c)
|
|
||||||
{
|
|
||||||
*p++ = c;
|
|
||||||
n--;
|
|
||||||
|
|
||||||
if (!n)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (n < 2)
|
|
||||||
break;
|
|
||||||
|
|
||||||
memcpy(p, s, 2);
|
|
||||||
|
|
||||||
p += 2;
|
|
||||||
n -= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
s += 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
strncpy(p, s, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
||||||
{
|
{
|
||||||
UINT8 *p;
|
UINT8 *p;
|
||||||
|
|
@ -1111,8 +1048,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
||||||
(dedicated ? SV_DEDICATED : 0)
|
(dedicated ? SV_DEDICATED : 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
CopyCaretColors(netbuffer->u.serverinfo.servername, cv_servername.string,
|
D_ParseCarets(netbuffer->u.serverinfo.servername, cv_servername.string, MAXSERVERNAME);
|
||||||
MAXSERVERNAME);
|
|
||||||
|
|
||||||
M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, 16);
|
M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, 16);
|
||||||
|
|
||||||
|
|
@ -1265,8 +1201,8 @@ static boolean SV_SendServerConfig(INT32 node)
|
||||||
|
|
||||||
memcpy(netbuffer->u.servercfg.server_context, server_context, 8);
|
memcpy(netbuffer->u.servercfg.server_context, server_context, 8);
|
||||||
|
|
||||||
strncpy(netbuffer->u.servercfg.server_name, cv_servername.string, MAXSERVERNAME);
|
D_ParseCarets(netbuffer->u.servercfg.server_name, cv_servername.string, MAXSERVERNAME);
|
||||||
strncpy(netbuffer->u.servercfg.server_contact, cv_server_contact.string, MAXSERVERCONTACT);
|
D_ParseCarets(netbuffer->u.servercfg.server_contact, cv_server_contact.string, MAXSERVERCONTACT);
|
||||||
|
|
||||||
{
|
{
|
||||||
const size_t len = sizeof (serverconfig_pak);
|
const size_t len = sizeof (serverconfig_pak);
|
||||||
|
|
@ -3438,8 +3374,8 @@ static void SV_GenContext(void)
|
||||||
server_context[i] = 'a'+(a-26);
|
server_context[i] = 'a'+(a-26);
|
||||||
}
|
}
|
||||||
|
|
||||||
strlcpy(connectedservername, cv_servername.string, MAXSERVERNAME);
|
D_ParseCarets(connectedservername, cv_servername.string, MAXSERVERNAME);
|
||||||
strlcpy(connectedservercontact, cv_server_contact.string, MAXSERVERCONTACT);
|
D_ParseCarets(connectedservercontact, cv_server_contact.string, MAXSERVERCONTACT);
|
||||||
}
|
}
|
||||||
#endif // TESTERS
|
#endif // TESTERS
|
||||||
|
|
||||||
|
|
@ -4340,7 +4276,6 @@ void HandleSigfail(const char *string)
|
||||||
*/
|
*/
|
||||||
static void HandleServerInfo(SINT8 node)
|
static void HandleServerInfo(SINT8 node)
|
||||||
{
|
{
|
||||||
char servername[MAXSERVERNAME];
|
|
||||||
// compute ping in ms
|
// compute ping in ms
|
||||||
const tic_t ticnow = I_GetTime();
|
const tic_t ticnow = I_GetTime();
|
||||||
const tic_t ticthen = (tic_t)LONG(netbuffer->u.serverinfo.time);
|
const tic_t ticthen = (tic_t)LONG(netbuffer->u.serverinfo.time);
|
||||||
|
|
@ -4351,8 +4286,7 @@ static void HandleServerInfo(SINT8 node)
|
||||||
[sizeof netbuffer->u.serverinfo.application - 1] = '\0';
|
[sizeof netbuffer->u.serverinfo.application - 1] = '\0';
|
||||||
netbuffer->u.serverinfo.gametypename
|
netbuffer->u.serverinfo.gametypename
|
||||||
[sizeof netbuffer->u.serverinfo.gametypename - 1] = '\0';
|
[sizeof netbuffer->u.serverinfo.gametypename - 1] = '\0';
|
||||||
memcpy(servername, netbuffer->u.serverinfo.servername, MAXSERVERNAME);
|
D_SanitizeKeepColors(netbuffer->u.serverinfo.servername, netbuffer->u.serverinfo.servername, MAXSERVERNAME);
|
||||||
CopyCaretColors(netbuffer->u.serverinfo.servername, servername, MAXSERVERNAME);
|
|
||||||
|
|
||||||
// If we have cause to reject it, it's not worth observing.
|
// If we have cause to reject it, it's not worth observing.
|
||||||
if (
|
if (
|
||||||
|
|
@ -4572,8 +4506,8 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
||||||
|
|
||||||
memcpy(server_context, netbuffer->u.servercfg.server_context, 8);
|
memcpy(server_context, netbuffer->u.servercfg.server_context, 8);
|
||||||
|
|
||||||
strlcpy(connectedservername, netbuffer->u.servercfg.server_name, MAXSERVERNAME);
|
D_SanitizeKeepColors(connectedservername, netbuffer->u.servercfg.server_name, MAXSERVERNAME);
|
||||||
strlcpy(connectedservercontact, netbuffer->u.servercfg.server_contact, MAXSERVERCONTACT);
|
D_SanitizeKeepColors(connectedservercontact, netbuffer->u.servercfg.server_contact, MAXSERVERCONTACT);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DISCORDRPC
|
#ifdef HAVE_DISCORDRPC
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@
|
||||||
|
|
||||||
#include "i_time.h"
|
#include "i_time.h"
|
||||||
#include "m_easing.h"
|
#include "m_easing.h"
|
||||||
|
#include "sanitize.h"
|
||||||
|
|
||||||
#ifdef PC_DOS
|
#ifdef PC_DOS
|
||||||
#include <stdio.h> // for snprintf
|
#include <stdio.h> // for snprintf
|
||||||
|
|
@ -532,12 +533,12 @@ static void M_DrawMenuTyping(void)
|
||||||
V_DrawFill(x + 4, y + 4 + 5, 1, 8+6, 121);
|
V_DrawFill(x + 4, y + 4 + 5, 1, 8+6, 121);
|
||||||
V_DrawFill(x + 5 + boxwidth - 8, y + 4 + 5, 1, 8+6, 121);
|
V_DrawFill(x + 5 + boxwidth - 8, y + 4 + 5, 1, 8+6, 121);
|
||||||
|
|
||||||
V_DrawString(x + 8, y + 12, 0, menutyping.cache);
|
INT32 textwidth = M_DrawCaretString(x + 8, y + 12, menutyping.cache, true);
|
||||||
if (skullAnimCounter < 4
|
if (skullAnimCounter < 4
|
||||||
&& menutyping.menutypingclose == false
|
&& menutyping.menutypingclose == false
|
||||||
&& menutyping.menutypingfade == (menutyping.keyboardtyping ? 9 : 18))
|
&& menutyping.menutypingfade == (menutyping.keyboardtyping ? 9 : 18))
|
||||||
{
|
{
|
||||||
V_DrawCharacter(x + 8 + V_StringWidth(menutyping.cache, 0), y + 12 + 1, '_', false);
|
V_DrawCharacter(x + 8 + textwidth, y + 12 + 1, '_', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const INT32 buttonwidth = ((boxwidth + 1)/NUMVIRTUALKEYSINROW);
|
const INT32 buttonwidth = ((boxwidth + 1)/NUMVIRTUALKEYSINROW);
|
||||||
|
|
@ -4493,7 +4494,7 @@ box_found:
|
||||||
V_DrawMenuString(x + (skullAnimCounter/5) + 7, y + 9, highlightflags, "\x1D");
|
V_DrawMenuString(x + (skullAnimCounter/5) + 7, y + 9, highlightflags, "\x1D");
|
||||||
}
|
}
|
||||||
|
|
||||||
V_DrawString(x + xoffs + 8, y + 9, 0, cv->string);
|
M_DrawCaretString(x + xoffs + 8, y + 9, cv->string, false);
|
||||||
|
|
||||||
y += LINEHEIGHT;
|
y += LINEHEIGHT;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
143
src/sanitize.cpp
Normal file
143
src/sanitize.cpp
Normal file
|
|
@ -0,0 +1,143 @@
|
||||||
|
// DR. ROBOTNIK'S RING RACERS
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2024 by James Robert Roman
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cctype>
|
||||||
|
#include <iterator>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
#include "doomtype.h"
|
||||||
|
#include "sanitize.h"
|
||||||
|
#include "v_draw.hpp"
|
||||||
|
|
||||||
|
using namespace srb2::sanitize;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
bool print_filter(char c)
|
||||||
|
{
|
||||||
|
return !std::isprint(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool color_filter(char c)
|
||||||
|
{
|
||||||
|
return print_filter(c) && (c & 0xF0) != 0x80; // color codes
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
std::string& filter_out(std::string& out, const std::string_view& range, F filter)
|
||||||
|
{
|
||||||
|
std::remove_copy_if(
|
||||||
|
range.begin(),
|
||||||
|
range.end(),
|
||||||
|
std::back_inserter(out),
|
||||||
|
filter
|
||||||
|
);
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
int hexconv(int c)
|
||||||
|
{
|
||||||
|
if (std::isdigit(c))
|
||||||
|
return c - '0';
|
||||||
|
|
||||||
|
c = std::toupper(c);
|
||||||
|
if (c >= 'A' && c <= 'F')
|
||||||
|
return 10 + (c - 'A');
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace
|
||||||
|
|
||||||
|
namespace srb2::sanitize
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string sanitize(std::string_view in, SanitizeMode mode)
|
||||||
|
{
|
||||||
|
std::string out;
|
||||||
|
return filter_out(out, in, [mode]
|
||||||
|
{
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case SanitizeMode::kPrintable:
|
||||||
|
return print_filter;
|
||||||
|
case SanitizeMode::kKeepColors:
|
||||||
|
return color_filter;
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string parse_carets(std::string_view in, ParseMode mode)
|
||||||
|
{
|
||||||
|
std::string out;
|
||||||
|
|
||||||
|
using std::size_t;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
size_t p = in.find('^');
|
||||||
|
|
||||||
|
// copy chars up until the caret
|
||||||
|
// but filter out codes outside of the ASCII range
|
||||||
|
filter_out(out, in.substr(0, p), print_filter);
|
||||||
|
|
||||||
|
if (p == in.npos)
|
||||||
|
{
|
||||||
|
break; // end of input
|
||||||
|
}
|
||||||
|
|
||||||
|
in.remove_prefix(p);
|
||||||
|
|
||||||
|
// need two characters for caret code
|
||||||
|
// convert to color byte
|
||||||
|
if (int c; in.length() > 1 && (c = hexconv(in[1])) != -1)
|
||||||
|
{
|
||||||
|
out.push_back(0x80 | c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode != ParseMode::kConsume)
|
||||||
|
{
|
||||||
|
// preserve caret code in output
|
||||||
|
filter_out(out, in.substr(0, 2), print_filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in.length() < 2)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
in.remove_prefix(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace srb2
|
||||||
|
|
||||||
|
void D_SanitizeKeepColors(char *out, const char *in, size_t out_size)
|
||||||
|
{
|
||||||
|
strlcpy(out, sanitize(in, SanitizeMode::kKeepColors).c_str(), out_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void D_ParseCarets(char *out, const char *in, size_t out_size)
|
||||||
|
{
|
||||||
|
strlcpy(out, parse_carets(in, ParseMode::kConsume).c_str(), out_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
INT32 M_DrawCaretString(INT32 x, INT32 y, const char *string, boolean preserve)
|
||||||
|
{
|
||||||
|
using srb2::Draw;
|
||||||
|
Draw::TextElement text(parse_carets(string, preserve ? ParseMode::kPreserve : ParseMode::kConsume));
|
||||||
|
text.font(Draw::Font::kConsole);
|
||||||
|
Draw(x, y).text(text);
|
||||||
|
return text.width();
|
||||||
|
}
|
||||||
55
src/sanitize.h
Normal file
55
src/sanitize.h
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
// DR. ROBOTNIK'S RING RACERS
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2024 by James Robert Roman
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef sanitize_h
|
||||||
|
#define sanitize_h
|
||||||
|
|
||||||
|
#include "doomtype.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
namespace srb2::sanitize
|
||||||
|
{
|
||||||
|
|
||||||
|
enum class SanitizeMode
|
||||||
|
{
|
||||||
|
kPrintable,
|
||||||
|
kKeepColors,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ParseMode
|
||||||
|
{
|
||||||
|
kConsume,
|
||||||
|
kPreserve,
|
||||||
|
};
|
||||||
|
|
||||||
|
// sanitizes string of all 0x80 codes
|
||||||
|
std::string sanitize(std::string_view in, SanitizeMode mode);
|
||||||
|
|
||||||
|
// sanitizes string of all 0x80 codes then parses caret codes
|
||||||
|
std::string parse_carets(std::string_view in, ParseMode mode);
|
||||||
|
|
||||||
|
}; // namespace srb2
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void D_SanitizeKeepColors(char *out, const char *in, size_t out_size); // SanitizeMode::kKeepColors
|
||||||
|
void D_ParseCarets(char *out, const char *in, size_t out_size); // ParseMode::kConsume
|
||||||
|
|
||||||
|
// returns string width in pixels
|
||||||
|
INT32 M_DrawCaretString(INT32 x, INT32 y, const char *string, boolean preserve);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // sanitize_h
|
||||||
Loading…
Add table
Reference in a new issue