4648: Add some checksum functions to the client r=def- a=heinrich5991

Let's see if it works out, if not, we can revert it.

## Checklist

- [x] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test if it works standalone, system.c especially
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: heinrich5991 <heinrich5991@gmail.com>
This commit is contained in:
bors[bot] 2022-01-31 22:42:24 +00:00 committed by GitHub
commit f15b3afd95
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
58 changed files with 718 additions and 168 deletions

View file

@ -98,6 +98,10 @@ jobs:
run: |
cd debug
${{ matrix.cmake-path }}cmake --build . --config Debug --target run_tests ${{ matrix.build-args }}
- name: Run debug server
env: ${{ matrix.env }}
run: |
cd debug
./DDNet-Server shutdown
- name: Build in release mode
@ -112,6 +116,10 @@ jobs:
run: |
cd release
${{ matrix.cmake-path }}cmake --build . --config Release --target run_tests ${{ matrix.build-args }}
- name: Run release server
env: ${{ matrix.env }}
run: |
cd release
./DDNet-Server shutdown
- name: Build headless client
@ -142,6 +150,11 @@ jobs:
run: |
cd fancy
${{ matrix.cmake-path }}cmake --build . --config RelWithDebInfo --target run_tests ${{ matrix.build-args }}
- name: Run fancy server
if: matrix.fancy
env: ${{ matrix.env }}
run: |
cd fancy
./DDNet-Server shutdown
- name: Package

1
.gitignore vendored
View file

@ -22,6 +22,7 @@ Makefile
Release
_CPack_Packages/
build.ninja
checksummed_*
cmake_install.cmake
gmock.pc
gmock_main.pc

View file

@ -293,7 +293,9 @@ endfunction()
function(set_src VAR GLOBBING DIRECTORY) # ...
set_glob(${VAR} ${GLOBBING} "c;cpp;h" ${DIRECTORY} ${ARGN})
set(${VAR} ${${VAR}} PARENT_SCOPE)
set(CHECKSUM_SRC ${CHECKSUM_SRC} ${${VAR}} PARENT_SCOPE)
endfunction()
set(CHECKSUM_SRC)
function(set_own_rpath TARGET)
if(NOT TARGET_OS STREQUAL "windows" AND NOT TARGET_OS STREQUAL "mac")
@ -570,7 +572,7 @@ endif()
if(TARGET_OS STREQUAL "windows")
set(PLATFORM_CLIENT)
set(PLATFORM_CLIENT_LIBS opengl32 winmm)
set(PLATFORM_LIBS ws2_32) # Windows sockets
set(PLATFORM_LIBS version ws2_32) # Windows sockets
elseif(TARGET_OS STREQUAL "mac")
find_library(CARBON Carbon)
find_library(COCOA Cocoa)
@ -1749,6 +1751,7 @@ if(CLIENT)
backend_sdl.h
blocklist_driver.cpp
blocklist_driver.h
checksum.h
client.cpp
client.h
demoedit.cpp
@ -1905,6 +1908,7 @@ if(CLIENT)
popups.cpp
)
set(GAME_GENERATED_CLIENT
src/game/generated/checksum.cpp
src/game/generated/client_data.cpp
src/game/generated/client_data.h
src/game/generated/client_data7.cpp
@ -2197,7 +2201,7 @@ if(TOOLS)
list(APPEND TARGETS_LINK ${TARGET_MASTERSRV} ${TARGET_TWPING})
set(TARGETS_TOOLS)
set_src(TOOLS GLOB src/tools
set_src(TOOLS_SRC GLOB src/tools
config_common.h
config_retrieve.cpp
config_store.cpp
@ -2215,7 +2219,7 @@ if(TOOLS)
unicode_confusables.cpp
uuid.cpp
)
foreach(ABS_T ${TOOLS})
foreach(ABS_T ${TOOLS_SRC})
file(RELATIVE_PATH T "${PROJECT_SOURCE_DIR}/src/tools/" ${ABS_T})
if(T MATCHES "\\.cpp$")
string(REGEX REPLACE "\\.cpp$" "" TOOL "${T}")
@ -2252,6 +2256,36 @@ if(TOOLS)
endif()
add_custom_target(everything DEPENDS ${TARGETS_OWN})
########################################################################
# CHECKSUM
########################################################################
if(DEV)
# Only do minimal checksumming in a DEV build.
set(CHECKSUM_SRC)
endif()
list(APPEND CHECKSUM_SRC
${PROJECT_SOURCE_DIR}/CMakeLists.txt
${PROJECT_SOURCE_DIR}/scripts/checksum.py
)
configure_file(cmake/checksummed_extra.txt checksummed_extra.txt)
string(REPLACE ";" "\n" CHECKSUM_SRC_FILE "${CHECKSUM_SRC}")
file(WRITE ${PROJECT_BINARY_DIR}/checksummed_files.txt ${CHECKSUM_SRC_FILE})
add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src/game/generated/checksum.cpp
COMMAND ${PYTHON_EXECUTABLE}
scripts/checksum.py
${PROJECT_BINARY_DIR}/checksummed_files.txt
${PROJECT_BINARY_DIR}/checksummed_extra.txt
> ${PROJECT_BINARY_DIR}/src/game/generated/checksum.cpp
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
DEPENDS
${CHECKSUM_SRC}
${PROJECT_BINARY_DIR}/checksummed_files.txt
${PROJECT_BINARY_DIR}/checksummed_extra.txt
scripts/checksum.py
)
########################################################################
# TESTS
########################################################################
@ -2275,6 +2309,7 @@ if(GTEST_FOUND OR DOWNLOAD_GTEST)
mapbugs.cpp
name_ban.cpp
netaddr.cpp
os.cpp
packer.cpp
prng.cpp
score.cpp

View file

@ -0,0 +1,22 @@
${CMAKE_VERSION}
${PROJECT_VERSION}
${TARGET_BITS}
${TARGET_CPU_ARCHITECTURE}
${CMAKE_SYSTEM_NAME}
${WEBSOCKETS}
${MYSQL}
${AUTOUPDATE}
${INFORM_UPDATE}
${VIDEORECORDER}
${UPNP}
${ANTIBOT}
${HEADLESS_CLIENT}
${CLIENT}
${SERVER}
${TOOLS}
${STEAM}
${DISCORD}
${DISCORD_DYNAMIC}
${DEV}
${CMAKE_BUILD_TYPE}
${CMAKE_CXX_COMPILER}

41
scripts/checksum.py Normal file
View file

@ -0,0 +1,41 @@
#!/usr/bin/env python3
import argparse
import hashlib
import os
os.chdir(os.path.dirname(__file__) + "/..")
def hash_bytes(b):
return "0x{}".format(hashlib.sha256(b).hexdigest()[:8])
def hash_file(filename):
with open(filename, "rb") as f:
return hash_bytes(f.read())
def main():
p = argparse.ArgumentParser(description="Checksums source files")
p.add_argument("list_file", metavar="LIST_FILE", help="File listing all the files to hash")
p.add_argument("extra_file", metavar="EXTRA_FILE", help="File containing extra strings to be hashed")
args = p.parse_args()
with open(args.list_file) as f:
files = f.read().splitlines()
with open(args.extra_file, "rb") as f:
extra = f.read().splitlines()
hashes_files = [hash_file(file) for file in files]
hashes_extra = [hash_bytes(line) for line in extra]
hashes = hashes_files + hashes_extra
print("""\
#include <engine/client/checksum.h>
void CChecksumData::InitFiles()
{
""", end="")
print("\tm_NumFiles = {};".format(len(hashes_files)))
print("\tm_NumExtra = {};".format(len(hashes_extra)))
for i, h in enumerate(hashes):
print("\tm_aFiles[0x{:03x}] = {};".format(i, h))
print("}")
if __name__ == "__main__":
main()

View file

@ -26,6 +26,7 @@
#if defined(CONF_FAMILY_UNIX)
#include <signal.h>
#include <sys/time.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <unistd.h>
@ -49,6 +50,7 @@
#define _task_user_
#include <Carbon/Carbon.h>
#include <mach-o/dyld.h>
#include <mach/mach_time.h>
#endif
@ -88,6 +90,47 @@ IOHANDLE io_stdin()
IOHANDLE io_stdout() { return (IOHANDLE)stdout; }
IOHANDLE io_stderr() { return (IOHANDLE)stderr; }
IOHANDLE io_current_exe()
{
// From https://stackoverflow.com/a/1024937.
#if defined(CONF_FAMILY_WINDOWS)
wchar_t wpath[IO_MAX_PATH_LENGTH];
char path[IO_MAX_PATH_LENGTH];
if(!GetModuleFileNameW(NULL, wpath, sizeof(wpath) / sizeof(wpath[0])))
{
return 0;
}
if(!WideCharToMultiByte(CP_UTF8, 0, wpath, -1, path, sizeof(path), NULL, NULL))
{
return 0;
}
return io_open(path, IOFLAG_READ);
#elif defined(CONF_PLATFORM_MACOS)
char path[IO_MAX_PATH_LENGTH];
uint32_t path_size = sizeof(path);
if(_NSGetExecutablePath(path, &path_size))
{
return 0;
}
return io_open(path, IOFLAG_READ);
#else
static const char *NAMES[] = {
"/proc/self/exe", // Linux, Android
"/proc/curproc/exe", // NetBSD
"/proc/curproc/file", // DragonFly
};
for(auto &name : NAMES)
{
IOHANDLE result = io_open(name, IOFLAG_READ);
if(result)
{
return result;
}
}
return 0;
#endif
}
typedef struct
{
DBG_LOGGER logger;
@ -3895,4 +3938,83 @@ void set_console_msg_color(const void *rgbvoid)
stdout_nonewline_logger.logger(buff, stdout_nonewline_logger.user);
#endif
}
int os_version_str(char *version, int length)
{
#if defined(CONF_FAMILY_WINDOWS)
const char *DLL = "C:\\Windows\\System32\\user32.dll";
DWORD handle;
DWORD size = GetFileVersionInfoSizeA(DLL, &handle);
if(!size)
{
return 1;
}
void *data = malloc(size);
if(!GetFileVersionInfoA(DLL, handle, size, data))
{
free(data);
return 1;
}
VS_FIXEDFILEINFO *fileinfo;
UINT unused;
if(!VerQueryValueA(data, "\\", (void **)&fileinfo, &unused))
{
free(data);
return 1;
}
str_format(version, length, "Windows %d.%d.%d.%d",
HIWORD(fileinfo->dwProductVersionMS),
LOWORD(fileinfo->dwProductVersionMS),
HIWORD(fileinfo->dwProductVersionLS),
LOWORD(fileinfo->dwProductVersionLS));
free(data);
return 0;
#else
struct utsname u;
if(uname(&u))
{
return 1;
}
char extra[128];
extra[0] = 0;
do
{
IOHANDLE os_release = io_open("/etc/os-release", IOFLAG_READ);
char buf[4096];
int read;
int offset;
char *newline;
if(!os_release)
{
break;
}
read = io_read(os_release, buf, sizeof(buf) - 1);
io_close(os_release);
buf[read] = 0;
if(str_startswith(buf, "PRETTY_NAME="))
{
offset = 0;
}
else
{
const char *found = str_find(buf, "\nPRETTY_NAME=");
if(!found)
{
break;
}
offset = found - buf + 1;
}
newline = (char *)str_find(buf + offset, "\n");
if(newline)
{
*newline = 0;
}
str_format(extra, sizeof(extra), "; %s", buf + offset + 12);
} while(0);
str_format(version, length, "%s %s (%s, %s)%s", u.sysname, u.release, u.machine, u.version, extra);
return 0;
#endif
}
}

View file

@ -333,6 +333,12 @@ IOHANDLE io_stdout();
*/
IOHANDLE io_stderr();
/*
Function: io_current_exe
Returns an <IOHANDLE> to the current executable.
*/
IOHANDLE io_current_exe();
typedef struct ASYNCIO ASYNCIO;
/*
@ -2326,6 +2332,20 @@ int secure_rand_below(int below);
*/
void set_console_msg_color(const void *rgbvoid);
/*
Function: os_version_str
Returns a human-readable version string of the operating system
Parameters:
version - Buffer to use for the output.
length - Length of the output buffer.
Returns:
0 - Success in getting the version.
1 - Failure in getting the version.
*/
int os_version_str(char *version, int length);
#if defined(__cplusplus)
}
#endif

View file

@ -23,6 +23,7 @@ enum
};
typedef bool (*CLIENTFUNC_FILTER)(const void *pData, int DataSize, void *pUser);
struct CChecksumData;
class IClient : public IInterface
{
@ -231,6 +232,7 @@ public:
virtual void GetSmoothTick(int *pSmoothTick, float *pSmoothIntraTick, float MixAmount) = 0;
virtual SWarning *GetCurWarning() = 0;
virtual CChecksumData *ChecksumData() = 0;
};
class IGameClient : public IInterface

View file

@ -0,0 +1,36 @@
#ifndef ENGINE_CLIENT_CHECKSUM_H
#define ENGINE_CLIENT_CHECKSUM_H
#include <engine/shared/config.h>
struct CChecksumData
{
int m_SizeofData;
char m_aVersionStr[128];
int m_Version;
char m_aOsVersion[256];
int64_t m_Start;
int m_Random;
int m_SizeofClient;
int m_SizeofGameClient;
float m_Zoom;
int m_SizeofConfig;
CConfig m_Config;
int m_NumCommands;
int m_aCommandsChecksum[1024];
int m_NumComponents;
int m_aComponentsChecksum[64];
int m_NumFiles;
int m_NumExtra;
unsigned m_aFiles[1024];
void InitFiles();
};
union CChecksum
{
char m_aBytes[sizeof(CChecksumData)];
CChecksumData m_Data;
};
#endif // ENGINE_CLIENT_CHECKSUM_H

View file

@ -402,6 +402,8 @@ CClient::CClient() :
m_FrameTimeAvg = 0.0001f;
m_BenchmarkFile = 0;
m_BenchmarkStopTime = 0;
mem_zero(&m_Checksum, sizeof(m_Checksum));
}
// ----- send functions -----
@ -1813,6 +1815,22 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy)
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf);
}
}
else if(Msg == NETMSG_CHECKSUM_REQUEST)
{
CUuid *pUuid = (CUuid *)Unpacker.GetRaw(sizeof(*pUuid));
if(Unpacker.Error())
{
return;
}
int Result = HandleChecksum(Conn, *pUuid, &Unpacker);
if(Result)
{
CMsgPacker Msg(NETMSG_CHECKSUM_ERROR, true);
Msg.AddRaw(pUuid, sizeof(*pUuid));
Msg.AddInt(Result);
SendMsg(Conn, &Msg, MSGFLAG_VITAL);
}
}
else if(Conn == CONN_MAIN && (pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_RCON_CMD_ADD)
{
const char *pName = Unpacker.GetString(CUnpacker::SANITIZE_CC);
@ -2942,6 +2960,9 @@ void CClient::Run()
m_Fifo.Init(m_pConsole, g_Config.m_ClInputFifo, CFGFLAG_CLIENT);
#endif
InitChecksum();
m_pConsole->InitChecksum(ChecksumData());
// loads the existing ddnet info file if it exists
LoadDDNetInfo();
// but still request the new one from server
@ -3805,6 +3826,125 @@ void CClient::ConchainServerBrowserUpdate(IConsole::IResult *pResult, void *pUse
((CClient *)pUserData)->ServerBrowserUpdate();
}
void CClient::InitChecksum()
{
CChecksumData *pData = &m_Checksum.m_Data;
pData->m_SizeofData = sizeof(*pData);
str_copy(pData->m_aVersionStr, GAME_NAME " " GAME_RELEASE_VERSION " (" CONF_PLATFORM_STRING "; " CONF_ARCH_STRING ")", sizeof(pData->m_aVersionStr));
pData->m_Start = time_get();
os_version_str(pData->m_aOsVersion, sizeof(pData->m_aOsVersion));
secure_random_fill(&pData->m_Random, sizeof(pData->m_Random));
pData->m_Version = GameClient()->DDNetVersion();
pData->m_SizeofClient = sizeof(*this);
pData->m_SizeofConfig = sizeof(pData->m_Config);
}
#ifndef DDNET_CHECKSUM_SALT
// salt@checksum.ddnet.tw: db877f2b-2ddb-3ba6-9f67-a6d169ec671d
#define DDNET_CHECKSUM_SALT \
{ \
{ \
0xdb, 0x87, 0x7f, 0x2b, 0x2d, 0xdb, 0x3b, 0xa6, \
0x9f, 0x67, 0xa6, 0xd1, 0x69, 0xec, 0x67, 0x1d, \
} \
}
#endif
int CClient::HandleChecksum(int Conn, CUuid Uuid, CUnpacker *pUnpacker)
{
int Start = pUnpacker->GetInt();
int Length = pUnpacker->GetInt();
if(pUnpacker->Error())
{
return 1;
}
if(Start < 0 || Length < 0 || Start > INT_MAX - Length)
{
return 2;
}
int End = Start + Length;
int ChecksumBytesEnd = minimum(End, (int)sizeof(m_Checksum.m_aBytes));
int FileStart = maximum(Start, (int)sizeof(m_Checksum.m_aBytes));
unsigned char aStartBytes[4];
unsigned char aEndBytes[4];
int_to_bytes_be(aStartBytes, Start);
int_to_bytes_be(aEndBytes, End);
if(Start <= (int)sizeof(m_Checksum.m_aBytes))
{
mem_zero(&m_Checksum.m_Data.m_Config, sizeof(m_Checksum.m_Data.m_Config));
#define CHECKSUM_RECORD(Flags) (((Flags)&CFGFLAG_CLIENT) == 0 || ((Flags)&CFGFLAG_INSENSITIVE) != 0)
#define MACRO_CONFIG_INT(Name, ScriptName, Def, Min, Max, Flags, Desc) \
if(CHECKSUM_RECORD(Flags)) \
{ \
m_Checksum.m_Data.m_Config.m_##Name = g_Config.m_##Name; \
}
#define MACRO_CONFIG_COL(Name, ScriptName, Def, Flags, Desc) \
if(CHECKSUM_RECORD(Flags)) \
{ \
m_Checksum.m_Data.m_Config.m_##Name = g_Config.m_##Name; \
}
#define MACRO_CONFIG_STR(Name, ScriptName, Len, Def, Flags, Desc) \
if(CHECKSUM_RECORD(Flags)) \
{ \
str_copy(m_Checksum.m_Data.m_Config.m_##Name, g_Config.m_##Name, sizeof(m_Checksum.m_Data.m_Config.m_##Name)); \
}
#include <engine/shared/config_variables.h>
#undef CHECKSUM_RECORD
#undef MACRO_CONFIG_INT
#undef MACRO_CONFIG_COL
#undef MACRO_CONFIG_STR
}
if(End > (int)sizeof(m_Checksum.m_aBytes))
{
if(m_OwnExecutableSize == 0)
{
m_OwnExecutable = io_current_exe();
// io_length returns -1 on error.
m_OwnExecutableSize = m_OwnExecutable ? io_length(m_OwnExecutable) : -1;
}
// Own executable not available.
if(m_OwnExecutableSize < 0)
{
return 3;
}
if(End - (int)sizeof(m_Checksum.m_aBytes) > m_OwnExecutableSize)
{
return 4;
}
}
SHA256_CTX Sha256Ctxt;
sha256_init(&Sha256Ctxt);
CUuid Salt = DDNET_CHECKSUM_SALT;
sha256_update(&Sha256Ctxt, &Salt, sizeof(Salt));
sha256_update(&Sha256Ctxt, &Uuid, sizeof(Uuid));
sha256_update(&Sha256Ctxt, aStartBytes, sizeof(aStartBytes));
sha256_update(&Sha256Ctxt, aEndBytes, sizeof(aEndBytes));
sha256_update(&Sha256Ctxt, m_Checksum.m_aBytes + Start, ChecksumBytesEnd - Start);
if(End > (int)sizeof(m_Checksum.m_aBytes))
{
unsigned char aBuf[2048];
if(io_seek(m_OwnExecutable, FileStart - sizeof(m_Checksum.m_aBytes), IOSEEK_START))
{
return 5;
}
for(int i = FileStart; i < End; i += sizeof(aBuf))
{
int Read = io_read(m_OwnExecutable, aBuf, minimum((int)sizeof(aBuf), End - i));
sha256_update(&Sha256Ctxt, aBuf, Read);
}
}
SHA256_DIGEST Sha256 = sha256_finish(&Sha256Ctxt);
CMsgPacker Msg(NETMSG_CHECKSUM_RESPONSE, true);
Msg.AddRaw(&Uuid, sizeof(Uuid));
Msg.AddRaw(&Sha256, sizeof(Sha256));
SendMsg(Conn, &Msg, MSGFLAG_VITAL);
return 0;
}
void CClient::SwitchWindowScreen(int Index)
{
// Todo SDL: remove this when fixed (changing screen when in fullscreen is bugged)

View file

@ -8,6 +8,7 @@
#include <base/hash.h>
#include <engine/client.h>
#include <engine/client/checksum.h>
#include <engine/client/demoedit.h>
#include <engine/client/friends.h>
#include <engine/client/ghost.h>
@ -279,6 +280,10 @@ class CClient : public IClient, public CDemoPlayer::IListener
IOHANDLE m_BenchmarkFile;
int64_t m_BenchmarkStopTime;
CChecksum m_Checksum;
int m_OwnExecutableSize = 0;
IOHANDLE m_OwnExecutable;
void UpdateDemoIntraTimers();
int MaxLatencyTicks() const;
int PredictionMargin() const;
@ -477,6 +482,9 @@ public:
void HandleDemoPath(const char *pPath);
void HandleMapPath(const char *pPath);
virtual void InitChecksum();
virtual int HandleChecksum(int Conn, CUuid Uuid, CUnpacker *pUnpacker);
// gfx
virtual void SwitchWindowScreen(int Index);
virtual void SetWindowParams(int FullscreenMode, bool IsBorderless);
@ -513,6 +521,7 @@ public:
virtual void GetSmoothTick(int *pSmoothTick, float *pSmoothIntraTick, float MixAmount);
virtual SWarning *GetCurWarning();
virtual CChecksumData *ChecksumData() { return &m_Checksum.m_Data; }
};
#endif

View file

@ -9,6 +9,8 @@
static const ColorRGBA gs_ConsoleDefaultColor(1, 1, 1, 1);
struct CChecksumData;
class IConsole : public IInterface
{
MACRO_INTERFACE("console", 0)
@ -107,6 +109,7 @@ public:
virtual char *Format(char *pBuf, int Size, const char *pFrom, const char *pStr) = 0;
virtual void Print(int Level, const char *pFrom, const char *pStr, ColorRGBA PrintColor = gs_ConsoleDefaultColor) = 0;
virtual void SetTeeHistorianCommandCallback(FTeeHistorianCommandCallback pfnCallback, void *pUser) = 0;
virtual void InitChecksum(CChecksumData *pData) const = 0;
virtual void SetAccessLevel(int AccessLevel) = 0;

View file

@ -41,6 +41,7 @@ enum
CFGFLAG_NONTEEHISTORIC = 1 << 9,
CFGFLAG_COLLIGHT = 1 << 10,
CFGFLAG_COLALPHA = 1 << 11,
CFGFLAG_INSENSITIVE = 1 << 12,
};
class CConfigManager : public IConfigManager

View file

@ -6,9 +6,9 @@
// TODO: remove this
#include "././game/variables.h"
MACRO_CONFIG_STR(PlayerName, player_name, 16, "", CFGFLAG_SAVE | CFGFLAG_CLIENT, "Name of the player")
MACRO_CONFIG_STR(PlayerClan, player_clan, 12, "", CFGFLAG_SAVE | CFGFLAG_CLIENT, "Clan of the player")
MACRO_CONFIG_INT(PlayerCountry, player_country, -1, -1, 1000, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Country of the player")
MACRO_CONFIG_STR(PlayerName, player_name, 16, "", CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_INSENSITIVE, "Name of the player")
MACRO_CONFIG_STR(PlayerClan, player_clan, 12, "", CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_INSENSITIVE, "Clan of the player")
MACRO_CONFIG_INT(PlayerCountry, player_country, -1, -1, 1000, CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_INSENSITIVE, "Country of the player")
MACRO_CONFIG_STR(Password, password, 32, "", CFGFLAG_CLIENT | CFGFLAG_SERVER | CFGFLAG_NONTEEHISTORIC, "Password to the server")
MACRO_CONFIG_STR(Logfile, logfile, 128, "", CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_SERVER, "Filename to log all output to")
MACRO_CONFIG_INT(ConsoleOutputLevel, console_output_level, 0, 0, 2, CFGFLAG_CLIENT | CFGFLAG_SERVER, "Adjusts the amount of information in the console")
@ -311,7 +311,7 @@ MACRO_CONFIG_INT(ClZoomBackgroundLayers, cl_zoom_background_layers, 0, 0, 1, CFG
MACRO_CONFIG_COL(ClBackgroundColor, cl_background_color, 128, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Background color") //0 0 128
MACRO_CONFIG_COL(ClBackgroundEntitiesColor, cl_background_entities_color, 128, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Background (entities) color") //0 0 128
MACRO_CONFIG_STR(ClBackgroundEntities, cl_background_entities, 100, "", CFGFLAG_CLIENT | CFGFLAG_SAVE, "Background (entities)")
MACRO_CONFIG_STR(ClRunOnJoin, cl_run_on_join, 100, "", CFGFLAG_CLIENT | CFGFLAG_SAVE, "Command to run when joining a server")
MACRO_CONFIG_STR(ClRunOnJoin, cl_run_on_join, 100, "", CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Command to run when joining a server")
// menu background map
MACRO_CONFIG_STR(ClMenuMap, cl_menu_map, 100, "auto", CFGFLAG_CLIENT | CFGFLAG_SAVE, "Background map in the menu")

View file

@ -7,6 +7,7 @@
#include <base/system.h>
#include <base/vmath.h>
#include <engine/client/checksum.h>
#include <engine/shared/protocol.h>
#include <engine/storage.h>
@ -342,6 +343,29 @@ void CConsole::SetTeeHistorianCommandCallback(FTeeHistorianCommandCallback pfnCa
m_pTeeHistorianCommandUserdata = pUser;
}
void CConsole::InitChecksum(CChecksumData *pData) const
{
pData->m_NumCommands = 0;
for(CCommand *pCommand = m_pFirstCommand; pCommand; pCommand = pCommand->m_pNext)
{
if(pData->m_NumCommands < (int)(sizeof(pData->m_aCommandsChecksum) / sizeof(pData->m_aCommandsChecksum[0])))
{
FCommandCallback pfnCallback = pCommand->m_pfnCallback;
void *pUserData = pCommand->m_pUserData;
while(pfnCallback == Con_Chain)
{
CChain *pChainInfo = static_cast<CChain *>(pUserData);
pfnCallback = pChainInfo->m_pfnCallback;
pUserData = pChainInfo->m_pCallbackUserData;
}
int CallbackBits = (uintptr_t)pfnCallback & 0xfff;
int *pTarget = &pData->m_aCommandsChecksum[pData->m_NumCommands];
*pTarget = ((uint8_t)pCommand->m_pName[0]) | ((uint8_t)pCommand->m_pName[1] << 8) | (CallbackBits << 16);
}
pData->m_NumCommands += 1;
}
}
bool CConsole::LineIsValid(const char *pStr)
{
if(!pStr || *pStr == 0)

View file

@ -222,6 +222,7 @@ public:
virtual char *Format(char *pBuf, int Size, const char *pFrom, const char *pStr);
virtual void Print(int Level, const char *pFrom, const char *pStr, ColorRGBA PrintColor = gs_ConsoleDefaultColor);
virtual void SetTeeHistorianCommandCallback(FTeeHistorianCommandCallback pfnCallback, void *pUser);
virtual void InitChecksum(CChecksumData *pData) const;
void SetAccessLevel(int AccessLevel) { m_AccessLevel = clamp(AccessLevel, (int)(ACCESS_LEVEL_ADMIN), (int)(ACCESS_LEVEL_USER)); }
void ResetServerGameSettings();

View file

@ -29,3 +29,6 @@ UUID(NETMSG_CAPABILITIES, "capabilities@ddnet.tw")
UUID(NETMSG_CLIENTVER, "clientver@ddnet.tw")
UUID(NETMSG_PINGEX, "ping@ddnet.tw")
UUID(NETMSG_PONGEX, "pong@ddnet.tw")
UUID(NETMSG_CHECKSUM_REQUEST, "checksum-request@ddnet.tw")
UUID(NETMSG_CHECKSUM_RESPONSE, "checksum-response@ddnet.tw")
UUID(NETMSG_CHECKSUM_ERROR, "checksum-error@ddnet.tw")

View file

@ -134,6 +134,10 @@ public:
* The component virtual destructor.
*/
virtual ~CComponent() {}
/**
* Gets the size of the non-abstract component.
*/
virtual int Sizeof() const = 0;
/**
* Get a pointer to the game client.
*/

View file

@ -32,10 +32,11 @@ protected:
public:
CBackground(int MapType = CMapLayers::TYPE_BACKGROUND_FORCE, bool OnlineOnly = true);
virtual ~CBackground();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnInit();
virtual void OnMapLoad();
virtual void OnRender();
virtual void OnInit() override;
virtual void OnMapLoad() override;
virtual void OnRender() override;
void LoadBackground();
};

View file

@ -24,12 +24,14 @@ class CBinds : public CComponent
public:
CBinds();
~CBinds();
virtual int Sizeof() const override { return sizeof(*this); }
class CBindsSpecial : public CComponent
{
public:
CBinds *m_pBinds;
virtual bool OnInput(IInput::CEvent Event);
virtual int Sizeof() const override { return sizeof(*this); }
virtual bool OnInput(IInput::CEvent Event) override;
};
enum
@ -57,8 +59,8 @@ public:
static const char *GetModifierName(int Modifier);
static const char *GetKeyBindModifiersName(int Modifier);
virtual void OnConsoleInit();
virtual bool OnInput(IInput::CEvent Event);
virtual void OnConsoleInit() override;
virtual bool OnInput(IInput::CEvent Event) override;
// DDRace

View file

@ -12,9 +12,10 @@ class CBroadcast : public CComponent
float m_BroadcastRenderOffset;
public:
virtual void OnReset();
virtual void OnRender();
virtual void OnMessage(int MsgType, void *pRawMsg);
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnReset() override;
virtual void OnRender() override;
virtual void OnMessage(int MsgType, void *pRawMsg) override;
};
#endif

View file

@ -40,12 +40,13 @@ public:
float m_ZoomSmoothingTarget;
CCamera();
virtual void OnRender();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnRender() override;
// DDRace
virtual void OnConsoleInit();
virtual void OnReset();
virtual void OnConsoleInit() override;
virtual void OnReset() override;
private:
static void ConZoomPlus(IConsole::IResult *pResult, void *pUserData);

View file

@ -119,6 +119,7 @@ class CChat : public CComponent
public:
CChat();
virtual int Sizeof() const override { return sizeof(*this); }
static constexpr float MESSAGE_PADDING_X = 5.0f;
static constexpr float MESSAGE_TEE_SIZE = 7.0f;
@ -137,15 +138,15 @@ public:
void RegisterCommand(const char *pName, const char *pParams, int flags, const char *pHelp);
void Echo(const char *pString);
virtual void OnWindowResize();
virtual void OnConsoleInit();
virtual void OnStateChange(int NewState, int OldState);
virtual void OnRender();
virtual void OnWindowResize() override;
virtual void OnConsoleInit() override;
virtual void OnStateChange(int NewState, int OldState) override;
virtual void OnRender() override;
virtual void RefindSkins();
virtual void OnPrepareLines();
virtual void OnRelease();
virtual void OnMessage(int MsgType, void *pRawMsg);
virtual bool OnInput(IInput::CEvent Event);
virtual void OnRelease() override;
virtual void OnMessage(int MsgType, void *pRawMsg) override;
virtual bool OnInput(IInput::CEvent Event) override;
void RebuildChat();
};

View file

@ -119,17 +119,18 @@ public:
};
CGameConsole();
virtual int Sizeof() const override { return sizeof(*this); }
void PrintLine(int Type, const char *pLine);
void RequireUsername(bool UsernameReq);
virtual void OnStateChange(int NewState, int OldState);
virtual void OnConsoleInit();
virtual void OnInit();
virtual void OnReset();
virtual void OnRender();
virtual void OnMessage(int MsgType, void *pRawMsg);
virtual bool OnInput(IInput::CEvent Events);
virtual void OnStateChange(int NewState, int OldState) override;
virtual void OnConsoleInit() override;
virtual void OnInit() override;
virtual void OnReset() override;
virtual void OnRender() override;
virtual void OnMessage(int MsgType, void *pRawMsg) override;
virtual bool OnInput(IInput::CEvent Events) override;
bool IsClosed() { return m_ConsoleState == CONSOLE_CLOSED; }
};

View file

@ -35,13 +35,14 @@ public:
int m_OtherFire;
CControls();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnReset();
virtual void OnRelease();
virtual void OnRender();
virtual void OnMessage(int MsgType, void *pRawMsg);
virtual bool OnMouseMove(float x, float y);
virtual void OnConsoleInit();
virtual void OnReset() override;
virtual void OnRelease() override;
virtual void OnRender() override;
virtual void OnMessage(int MsgType, void *pRawMsg) override;
virtual bool OnMouseMove(float x, float y) override;
virtual void OnConsoleInit() override;
virtual void OnPlayerDeath();
int SnapInput(int *pData);

View file

@ -18,7 +18,8 @@ public:
bool operator<(const CCountryFlag &Other) const { return str_comp(m_aCountryCodeString, Other.m_aCountryCodeString) < 0; }
};
void OnInit();
virtual int Sizeof() const override { return sizeof(*this); }
void OnInit() override;
int Num() const;
const CCountryFlag *GetByCountryCode(int CountryCode) const;

View file

@ -31,10 +31,11 @@ class CDamageInd : public CComponent
public:
CDamageInd();
virtual int Sizeof() const override { return sizeof(*this); }
void Create(vec2 Pos, vec2 Dir);
void Reset();
virtual void OnRender();
virtual void OnInit();
virtual void OnRender() override;
virtual void OnInit() override;
};
#endif

View file

@ -11,7 +11,8 @@ class CDebugHud : public CComponent
void RenderHint();
public:
virtual void OnRender();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnRender() override;
};
#endif

View file

@ -11,8 +11,9 @@ class CEffects : public CComponent
public:
CEffects();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnRender();
virtual void OnRender() override;
void BulletTrail(vec2 Pos, float Alpha = 1.f, float TimePassed = 0.f);
void SmokeTrail(vec2 Pos, vec2 Vel, float Alpha = 1.f, float TimePassed = 0.f);

View file

@ -21,12 +21,13 @@ class CEmoticon : public CComponent
public:
CEmoticon();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnReset();
virtual void OnConsoleInit();
virtual void OnRender();
virtual void OnRelease();
virtual bool OnMouseMove(float x, float y);
virtual void OnReset() override;
virtual void OnConsoleInit() override;
virtual void OnRender() override;
virtual void OnRelease() override;
virtual bool OnMouseMove(float x, float y) override;
void Emote(int Emoticon);
void EyeEmote(int EyeEmote);

View file

@ -22,6 +22,7 @@ class CFlow : public CComponent
public:
CFlow();
virtual int Sizeof() const override { return sizeof(*this); }
vec2 Get(vec2 Pos);
void Add(vec2 Pos, vec2 Vel, float Size);

View file

@ -149,13 +149,14 @@ public:
bool m_AllowRestart;
CGhost();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnRender();
virtual void OnConsoleInit();
virtual void OnReset();
virtual void OnMessage(int MsgType, void *pRawMsg);
virtual void OnMapLoad();
virtual void OnShutdown();
virtual void OnRender() override;
virtual void OnConsoleInit() override;
virtual void OnReset() override;
virtual void OnMessage(int MsgType, void *pRawMsg) override;
virtual void OnMapLoad() override;
virtual void OnShutdown() override;
void OnNewSnapshot();
void OnNewPredictedSnapshot();

View file

@ -64,16 +64,17 @@ class CHud : public CComponent
public:
CHud();
virtual int Sizeof() const override { return sizeof(*this); }
void ResetHudContainers();
virtual void OnWindowResize();
virtual void OnReset();
virtual void OnRender();
virtual void OnInit();
virtual void OnWindowResize() override;
virtual void OnReset() override;
virtual void OnRender() override;
virtual void OnInit() override;
// DDRace
virtual void OnMessage(int MsgType, void *pRawMsg);
virtual void OnMessage(int MsgType, void *pRawMsg) override;
private:
void RenderRecord();

View file

@ -16,8 +16,9 @@ class CItems : public CComponent
int m_ItemsQuadContainerIndex;
public:
virtual void OnRender();
virtual void OnInit();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnRender() override;
virtual void OnInit() override;
void ReconstructSmokeTrail(const CProjectileData *pCurrent, int DestroyTick);
};

View file

@ -53,11 +53,12 @@ public:
CKillMsg m_aKillmsgs[MAX_KILLMSGS];
int m_KillmsgCurrent;
virtual void OnWindowResize();
virtual void OnReset();
virtual void OnRender();
virtual void OnMessage(int MsgType, void *pRawMsg);
virtual void OnInit();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnWindowResize() override;
virtual void OnReset() override;
virtual void OnRender() override;
virtual void OnMessage(int MsgType, void *pRawMsg) override;
virtual void OnInit() override;
void RefindSkins();
};

View file

@ -58,13 +58,14 @@ class CMapImages : public CComponent
public:
CMapImages();
CMapImages(int TextureSize);
virtual int Sizeof() const override { return sizeof(*this); }
IGraphics::CTextureHandle Get(int Index) const { return m_aTextures[Index]; }
int Num() const { return m_Count; }
void OnMapLoadImpl(class CLayers *pLayers, class IMap *pMap);
virtual void OnMapLoad();
virtual void OnInit();
virtual void OnMapLoad() override;
virtual void OnInit() override;
void LoadBackground(class CLayers *pLayers, class IMap *pMap);
// DDRace

View file

@ -146,9 +146,10 @@ public:
CMapLayers(int Type, bool OnlineOnly = true);
virtual ~CMapLayers();
virtual void OnInit();
virtual void OnRender();
virtual void OnMapLoad();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnInit() override;
virtual void OnRender() override;
virtual void OnMapLoad() override;
void RenderTileLayer(int LayerIndex, ColorRGBA *pColor, CMapItemLayerTilemap *pTileLayer, CMapItemGroup *pGroup);
void RenderTileBorder(int LayerIndex, ColorRGBA *pColor, CMapItemLayerTilemap *pTileLayer, CMapItemGroup *pGroup, int BorderX0, int BorderY0, int BorderX1, int BorderY1, int ScreenWidthTileCount, int ScreenHeightTileCount);

View file

@ -30,10 +30,11 @@ class CMapSounds : public CComponent
public:
CMapSounds();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnMapLoad();
virtual void OnRender();
virtual void OnStateChange(int NewState, int OldState);
virtual void OnMapLoad() override;
virtual void OnRender() override;
virtual void OnStateChange(int NewState, int OldState) override;
};
#endif // GAME_CLIENT_COMPONENTS_MAPSOUNDS_H

View file

@ -93,6 +93,7 @@ public:
CMenuBackground();
~CMenuBackground() override {}
virtual int Sizeof() const override { return sizeof(*this); }
void OnInit() override;
void OnMapLoad() override;

View file

@ -52,7 +52,8 @@ public:
IInput::CEvent m_Key;
int m_Modifier;
CMenusKeyBinder();
virtual bool OnInput(IInput::CEvent Event);
virtual int Sizeof() const override { return sizeof(*this); }
virtual bool OnInput(IInput::CEvent Event) override;
};
class CMenus : public CComponent
@ -514,6 +515,7 @@ public:
static CMenusKeyBinder m_Binder;
CMenus();
virtual int Sizeof() const override { return sizeof(*this); }
void RenderLoading();
void RenderUpdating(const char *pCaption, int current = 0, int total = 0);
@ -521,14 +523,14 @@ public:
bool IsActive() const { return m_MenuActive; }
void KillServer();
virtual void OnInit();
virtual void OnInit() override;
virtual void OnStateChange(int NewState, int OldState);
virtual void OnReset();
virtual void OnRender();
virtual bool OnInput(IInput::CEvent Event);
virtual bool OnMouseMove(float x, float y);
virtual void OnShutdown();
virtual void OnStateChange(int NewState, int OldState) override;
virtual void OnReset() override;
virtual void OnRender() override;
virtual bool OnInput(IInput::CEvent Event) override;
virtual bool OnMouseMove(float x, float y) override;
virtual void OnShutdown() override;
enum
{

View file

@ -12,13 +12,14 @@ class CMotd : public CComponent
public:
char m_aServerMotd[900];
virtual int Sizeof() const override { return sizeof(*this); }
void Clear();
bool IsActive();
virtual void OnRender();
virtual void OnStateChange(int NewState, int OldState);
virtual void OnMessage(int MsgType, void *pRawMsg);
virtual bool OnInput(IInput::CEvent Event);
virtual void OnRender() override;
virtual void OnStateChange(int NewState, int OldState) override;
virtual void OnMessage(int MsgType, void *pRawMsg) override;
virtual bool OnInput(IInput::CEvent Event) override;
};
#endif

View file

@ -51,9 +51,10 @@ class CNamePlates : public CComponent
void ResetNamePlates();
public:
virtual void OnWindowResize();
virtual void OnInit();
virtual void OnRender();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnWindowResize() override;
virtual void OnInit() override;
virtual void OnRender() override;
void SetPlayers(class CPlayers *pPlayers);
};

View file

@ -62,12 +62,13 @@ public:
};
CParticles();
virtual int Sizeof() const override { return sizeof(*this); }
void Add(int Group, CParticle *pPart, float TimePassed = 0.f);
virtual void OnReset();
virtual void OnRender();
virtual void OnInit();
virtual void OnReset() override;
virtual void OnRender() override;
virtual void OnInit() override;
private:
int m_ParticleQuadContainerIndex;
@ -89,7 +90,8 @@ private:
{
public:
CParticles *m_pParts;
virtual void OnRender() { m_pParts->RenderGroup(TGROUP); }
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnRender() override { m_pParts->RenderGroup(TGROUP); }
};
CRenderGroup<GROUP_PROJECTILE_TRAIL> m_RenderTrail;

View file

@ -33,8 +33,9 @@ class CPlayers : public CComponent
public:
vec2 m_CurPredictedPos[MAX_CLIENTS];
virtual void OnInit();
virtual void OnRender();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnInit() override;
virtual void OnRender() override;
};
#endif

View file

@ -36,12 +36,13 @@ public:
bool m_AllowRestart;
CRaceDemo();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnReset();
virtual void OnStateChange(int NewState, int OldState);
virtual void OnMessage(int MsgType, void *pRawMsg);
virtual void OnMapLoad();
virtual void OnShutdown();
virtual void OnReset() override;
virtual void OnStateChange(int NewState, int OldState) override;
virtual void OnMessage(int MsgType, void *pRawMsg) override;
virtual void OnMapLoad() override;
virtual void OnShutdown() override;
void OnNewSnapshot();
};

View file

@ -19,16 +19,17 @@ class CScoreboard : public CComponent
public:
CScoreboard();
virtual void OnReset();
virtual void OnConsoleInit();
virtual void OnRender();
virtual void OnRelease();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnReset() override;
virtual void OnConsoleInit() override;
virtual void OnRender() override;
virtual void OnRelease() override;
bool Active();
// DDRace
virtual void OnMessage(int MsgType, void *pRawMsg);
virtual void OnMessage(int MsgType, void *pRawMsg) override;
private:
float m_ServerRecord;

View file

@ -17,7 +17,7 @@ public:
CSkins *m_pSkins;
protected:
virtual int OnCompletion(int State);
virtual int OnCompletion(int State) override;
public:
CGetPngFile(CSkins *pSkins, IStorage *pStorage, const char *pUrl, const char *pDest, int StorageType = -2, CTimeout Timeout = CTimeout{4000, 500, 5}, HTTPLOG LogProgress = HTTPLOG::ALL);
@ -35,7 +35,8 @@ public:
bool operator==(const char *pOther) const { return !str_comp(m_aName, pOther); }
};
void OnInit();
virtual int Sizeof() const override { return sizeof(*this); }
void OnInit() override;
void Refresh();
int Num();

View file

@ -50,10 +50,11 @@ public:
CHN_MAPSOUND,
};
virtual void OnInit();
virtual void OnReset();
virtual void OnStateChange(int NewState, int OldState);
virtual void OnRender();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnInit() override;
virtual void OnReset() override;
virtual void OnStateChange(int NewState, int OldState) override;
virtual void OnRender() override;
void ClearQueue();
void Enqueue(int Channel, int SetId);

View file

@ -33,12 +33,13 @@ class CSpectator : public CComponent
public:
CSpectator();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnConsoleInit();
virtual bool OnMouseMove(float x, float y);
virtual void OnRender();
virtual void OnRelease();
virtual void OnReset();
virtual void OnConsoleInit() override;
virtual bool OnMouseMove(float x, float y) override;
virtual void OnRender() override;
virtual void OnRelease() override;
virtual void OnReset() override;
void Spectate(int SpectatorID);
};

View file

@ -20,11 +20,12 @@ private:
public:
CStatboard();
virtual void OnReset();
virtual void OnConsoleInit();
virtual void OnRender();
virtual void OnRelease();
virtual void OnMessage(int MsgType, void *pRawMsg);
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnReset() override;
virtual void OnConsoleInit() override;
virtual void OnRender() override;
virtual void OnRelease() override;
virtual void OnMessage(int MsgType, void *pRawMsg) override;
bool IsActive();
};

View file

@ -35,10 +35,11 @@ public:
CVoteOptionClient *m_pRecycleLast;
CVoting();
virtual void OnReset();
virtual void OnConsoleInit();
virtual void OnMessage(int Msgtype, void *pRawMsg);
virtual void OnRender();
virtual int Sizeof() const override { return sizeof(*this); }
virtual void OnReset() override;
virtual void OnConsoleInit() override;
virtual void OnMessage(int Msgtype, void *pRawMsg) override;
virtual void OnRender() override;
void RenderBars(CUIRect Bars, bool Text);

View file

@ -3,6 +3,7 @@
#include <limits>
#include <engine/client/checksum.h>
#include <engine/demo.h>
#include <engine/editor.h>
#include <engine/engine.h>
@ -322,6 +323,19 @@ void CGameClient::OnInit()
// Agressively try to grab window again since some Windows users report
// window not being focussed after starting client.
Graphics()->SetWindowGrab(true);
CChecksumData *pChecksum = Client()->ChecksumData();
pChecksum->m_SizeofGameClient = sizeof(*this);
pChecksum->m_NumComponents = m_All.m_Num;
for(int i = 0; i < m_All.m_Num; i++)
{
if(i >= (int)(sizeof(pChecksum->m_aComponentsChecksum) / sizeof(pChecksum->m_aComponentsChecksum[0])))
{
break;
}
int Size = m_All.m_paComponents[i]->Sizeof();
pChecksum->m_aComponentsChecksum[i] = Size;
}
}
void CGameClient::OnUpdate()
@ -1615,6 +1629,7 @@ void CGameClient::OnNewSnapshot()
RenderTools()->CalcScreenParams(Graphics()->ScreenAspect(), ZoomToSend, &x, &y);
Msg.m_X = x;
Msg.m_Y = y;
Client()->ChecksumData()->m_Zoom = ZoomToSend;
CMsgPacker Packer(Msg.MsgID(), false);
Msg.Pack(&Packer);
if(ZoomToSend != m_LastZoom)

View file

@ -62,20 +62,20 @@ MACRO_CONFIG_INT(ClThreadsoundloading, cl_threadsoundloading, 0, 0, 1, CFGFLAG_C
MACRO_CONFIG_INT(ClWarningTeambalance, cl_warning_teambalance, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Warn about team balance")
MACRO_CONFIG_INT(ClMouseDeadzone, cl_mouse_deadzone, 0, 0, 3000, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Deadzone for the camera to follow the cursor")
MACRO_CONFIG_INT(ClMouseFollowfactor, cl_mouse_followfactor, 0, 0, 200, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Factor for the camera to follow the cursor")
MACRO_CONFIG_INT(ClMouseMaxDistance, cl_mouse_max_distance, 400, 0, 5000, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Maximum cursor distance")
MACRO_CONFIG_INT(ClMouseMinDistance, cl_mouse_min_distance, 0, 0, 5000, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Minimum cursor distance")
MACRO_CONFIG_INT(ClMouseDeadzone, cl_mouse_deadzone, 0, 0, 3000, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Deadzone for the camera to follow the cursor")
MACRO_CONFIG_INT(ClMouseFollowfactor, cl_mouse_followfactor, 0, 0, 200, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Factor for the camera to follow the cursor")
MACRO_CONFIG_INT(ClMouseMaxDistance, cl_mouse_max_distance, 400, 0, 5000, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Maximum cursor distance")
MACRO_CONFIG_INT(ClMouseMinDistance, cl_mouse_min_distance, 0, 0, 5000, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Minimum cursor distance")
MACRO_CONFIG_INT(ClDyncam, cl_dyncam, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Enable dyncam")
MACRO_CONFIG_INT(ClDyncamMaxDistance, cl_dyncam_max_distance, 1000, 0, 2000, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Maximum dynamic camera cursor distance")
MACRO_CONFIG_INT(ClDyncamMinDistance, cl_dyncam_min_distance, 0, 0, 2000, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Minimum dynamic camera cursor distance")
MACRO_CONFIG_INT(ClDyncamMousesens, cl_dyncam_mousesens, 0, 0, 100000, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Mouse sens used when dyncam is toggled on")
MACRO_CONFIG_INT(ClDyncamDeadzone, cl_dyncam_deadzone, 300, 1, 1300, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Deadzone for the dynamic camera to follow the cursor")
MACRO_CONFIG_INT(ClDyncamFollowFactor, cl_dyncam_follow_factor, 60, 0, 200, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Factor for the dynamic camera to follow the cursor")
MACRO_CONFIG_INT(ClDyncam, cl_dyncam, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Enable dyncam")
MACRO_CONFIG_INT(ClDyncamMaxDistance, cl_dyncam_max_distance, 1000, 0, 2000, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Maximum dynamic camera cursor distance")
MACRO_CONFIG_INT(ClDyncamMinDistance, cl_dyncam_min_distance, 0, 0, 2000, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Minimum dynamic camera cursor distance")
MACRO_CONFIG_INT(ClDyncamMousesens, cl_dyncam_mousesens, 0, 0, 100000, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Mouse sens used when dyncam is toggled on")
MACRO_CONFIG_INT(ClDyncamDeadzone, cl_dyncam_deadzone, 300, 1, 1300, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Deadzone for the dynamic camera to follow the cursor")
MACRO_CONFIG_INT(ClDyncamFollowFactor, cl_dyncam_follow_factor, 60, 0, 200, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Factor for the dynamic camera to follow the cursor")
MACRO_CONFIG_INT(ClDyncamSmoothness, cl_dyncam_smoothness, 0, 0, 100, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Transition amount of the camera movement, 0=instant, 100=slow and smooth")
MACRO_CONFIG_INT(ClDyncamStabilizing, cl_dyncam_stabilizing, 0, 0, 100, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Amount of camera slowdown during fast cursor movement. High value can cause delay in camera movement")
MACRO_CONFIG_INT(ClDyncamSmoothness, cl_dyncam_smoothness, 0, 0, 100, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Transition amount of the camera movement, 0=instant, 100=slow and smooth")
MACRO_CONFIG_INT(ClDyncamStabilizing, cl_dyncam_stabilizing, 0, 0, 100, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Amount of camera slowdown during fast cursor movement. High value can cause delay in camera movement")
MACRO_CONFIG_INT(EdZoomTarget, ed_zoom_target, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Zoom to the current mouse target")
MACRO_CONFIG_INT(EdShowkeys, ed_showkeys, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "")
@ -100,17 +100,17 @@ MACRO_CONFIG_INT(ClDefaultZoom, cl_default_zoom, 10, 0, 20, CFGFLAG_CLIENT | CFG
MACRO_CONFIG_INT(ClSmoothZoomTime, cl_smooth_zoom_time, 250, 0, 5000, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Time of smooth zoom animation in ms (0 for off)")
MACRO_CONFIG_INT(ClLimitMaxZoomLevel, cl_limit_max_zoom_level, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Specifies, if zooming should be limited or not (0 = no limit)")
MACRO_CONFIG_INT(ClPlayerUseCustomColor, player_use_custom_color, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Toggles usage of custom colors")
MACRO_CONFIG_COL(ClPlayerColorBody, player_color_body, 65408, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_COLLIGHT, "Player body color")
MACRO_CONFIG_COL(ClPlayerColorFeet, player_color_feet, 65408, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_COLLIGHT, "Player feet color")
MACRO_CONFIG_STR(ClPlayerSkin, player_skin, 24, "default", CFGFLAG_CLIENT | CFGFLAG_SAVE, "Player skin")
MACRO_CONFIG_INT(ClPlayerUseCustomColor, player_use_custom_color, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Toggles usage of custom colors")
MACRO_CONFIG_COL(ClPlayerColorBody, player_color_body, 65408, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_COLLIGHT | CFGFLAG_INSENSITIVE, "Player body color")
MACRO_CONFIG_COL(ClPlayerColorFeet, player_color_feet, 65408, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_COLLIGHT | CFGFLAG_INSENSITIVE, "Player feet color")
MACRO_CONFIG_STR(ClPlayerSkin, player_skin, 24, "default", CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Player skin")
MACRO_CONFIG_STR(ClSkinPrefix, cl_skin_prefix, 12, "", CFGFLAG_CLIENT | CFGFLAG_SAVE, "Replace the skins by skins with this prefix (e.g. kitty, santa)")
MACRO_CONFIG_INT(ClFatSkins, cl_fat_skins, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Enable fat skins")
MACRO_CONFIG_INT(UiPage, ui_page, 9, 6, 10, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Interface page")
MACRO_CONFIG_INT(UiSettingsPage, ui_settings_page, 0, 0, 9, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Interface settings page")
MACRO_CONFIG_INT(UiToolboxPage, ui_toolbox_page, 0, 0, 2, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Toolbox page")
MACRO_CONFIG_STR(UiServerAddress, ui_server_address, 64, "localhost:8303", CFGFLAG_CLIENT | CFGFLAG_SAVE, "Interface server address")
MACRO_CONFIG_STR(UiServerAddress, ui_server_address, 64, "localhost:8303", CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Interface server address")
MACRO_CONFIG_INT(UiScale, ui_scale, 100, 50, 150, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Interface scale")
MACRO_CONFIG_INT(UiMousesens, ui_mousesens, 200, 1, 100000, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Mouse sensitivity for menus/editor")
@ -126,24 +126,24 @@ MACRO_CONFIG_INT(UiUnreadNews, ui_unread_news, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG
MACRO_CONFIG_INT(GfxNoclip, gfx_noclip, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Disable clipping")
// dummy
MACRO_CONFIG_STR(ClDummyName, dummy_name, 16, "", CFGFLAG_SAVE | CFGFLAG_CLIENT, "Name of the dummy")
MACRO_CONFIG_STR(ClDummyClan, dummy_clan, 12, "", CFGFLAG_SAVE | CFGFLAG_CLIENT, "Clan of the dummy")
MACRO_CONFIG_INT(ClDummyCountry, dummy_country, -1, -1, 1000, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Country of the Dummy")
MACRO_CONFIG_INT(ClDummyUseCustomColor, dummy_use_custom_color, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Toggles usage of custom colors")
MACRO_CONFIG_COL(ClDummyColorBody, dummy_color_body, 65408, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_COLLIGHT, "Dummy body color")
MACRO_CONFIG_COL(ClDummyColorFeet, dummy_color_feet, 65408, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_COLLIGHT, "Dummy feet color")
MACRO_CONFIG_STR(ClDummySkin, dummy_skin, 24, "default", CFGFLAG_CLIENT | CFGFLAG_SAVE, "Dummy skin")
MACRO_CONFIG_INT(ClDummy, cl_dummy, 0, 0, 1, CFGFLAG_CLIENT, "0 - player / 1 - dummy")
MACRO_CONFIG_INT(ClDummyHammer, cl_dummy_hammer, 0, 0, 1, CFGFLAG_CLIENT, "Whether dummy is hammering for a hammerfly")
MACRO_CONFIG_INT(ClDummyResetOnSwitch, cl_dummy_resetonswitch, 0, 0, 2, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Whether dummy or player should stop pressing keys when you switch. 0 = off, 1 = dummy, 2 = player")
MACRO_CONFIG_INT(ClDummyRestoreWeapon, cl_dummy_restore_weapon, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Whether dummy should switch to last weapon after hammerfly")
MACRO_CONFIG_INT(ClDummyCopyMoves, cl_dummy_copy_moves, 0, 0, 1, CFGFLAG_CLIENT, "Whether dummy should copy your moves")
MACRO_CONFIG_STR(ClDummyName, dummy_name, 16, "", CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_INSENSITIVE, "Name of the dummy")
MACRO_CONFIG_STR(ClDummyClan, dummy_clan, 12, "", CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_INSENSITIVE, "Clan of the dummy")
MACRO_CONFIG_INT(ClDummyCountry, dummy_country, -1, -1, 1000, CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_INSENSITIVE, "Country of the Dummy")
MACRO_CONFIG_INT(ClDummyUseCustomColor, dummy_use_custom_color, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Toggles usage of custom colors")
MACRO_CONFIG_COL(ClDummyColorBody, dummy_color_body, 65408, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_COLLIGHT | CFGFLAG_INSENSITIVE, "Dummy body color")
MACRO_CONFIG_COL(ClDummyColorFeet, dummy_color_feet, 65408, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_COLLIGHT | CFGFLAG_INSENSITIVE, "Dummy feet color")
MACRO_CONFIG_STR(ClDummySkin, dummy_skin, 24, "default", CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Dummy skin")
MACRO_CONFIG_INT(ClDummy, cl_dummy, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_INSENSITIVE, "0 - player / 1 - dummy")
MACRO_CONFIG_INT(ClDummyHammer, cl_dummy_hammer, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_INSENSITIVE, "Whether dummy is hammering for a hammerfly")
MACRO_CONFIG_INT(ClDummyResetOnSwitch, cl_dummy_resetonswitch, 0, 0, 2, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Whether dummy or player should stop pressing keys when you switch. 0 = off, 1 = dummy, 2 = player")
MACRO_CONFIG_INT(ClDummyRestoreWeapon, cl_dummy_restore_weapon, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Whether dummy should switch to last weapon after hammerfly")
MACRO_CONFIG_INT(ClDummyCopyMoves, cl_dummy_copy_moves, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_INSENSITIVE, "Whether dummy should copy your moves")
// more controlable dummy command
MACRO_CONFIG_INT(ClDummyControl, cl_dummy_control, 0, 0, 1, CFGFLAG_CLIENT, "Whether can you control dummy at the same time (cl_dummy_jump, cl_dummy_fire, cl_dummy_hook)")
MACRO_CONFIG_INT(ClDummyJump, cl_dummy_jump, 0, 0, 1, CFGFLAG_CLIENT, "Whether dummy is jumping (requires cl_dummy_control 1)")
MACRO_CONFIG_INT(ClDummyFire, cl_dummy_fire, 0, 0, 1, CFGFLAG_CLIENT, "Whether dummy is firing (requires cl_dummy_control 1)")
MACRO_CONFIG_INT(ClDummyHook, cl_dummy_hook, 0, 0, 1, CFGFLAG_CLIENT, "Whether dummy is hooking (requires cl_dummy_control 1)")
MACRO_CONFIG_INT(ClDummyControl, cl_dummy_control, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_INSENSITIVE, "Whether can you control dummy at the same time (cl_dummy_jump, cl_dummy_fire, cl_dummy_hook)")
MACRO_CONFIG_INT(ClDummyJump, cl_dummy_jump, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_INSENSITIVE, "Whether dummy is jumping (requires cl_dummy_control 1)")
MACRO_CONFIG_INT(ClDummyFire, cl_dummy_fire, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_INSENSITIVE, "Whether dummy is firing (requires cl_dummy_control 1)")
MACRO_CONFIG_INT(ClDummyHook, cl_dummy_hook, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_INSENSITIVE, "Whether dummy is hooking (requires cl_dummy_control 1)")
// start menu
MACRO_CONFIG_INT(ClShowStartMenuImages, cl_show_start_menu_images, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show start menu images")

View file

@ -61,3 +61,10 @@ TEST(Io, ReadBom6)
{
TestFileRead("\xef\xbb\xbfxyz\xef\xbb\xbf", true, "xyz\xef\xbb\xbf");
}
TEST(Io, CurrentExe)
{
IOHANDLE CurrentExe = io_current_exe();
ASSERT_TRUE(CurrentExe);
EXPECT_GE(io_length(CurrentExe), 1024);
io_close(CurrentExe);
}

11
src/test/os.cpp Normal file
View file

@ -0,0 +1,11 @@
#include "test.h"
#include <gtest/gtest.h>
#include <base/system.h>
TEST(Os, VersionStr)
{
char aVersion[128];
EXPECT_FALSE(os_version_str(aVersion, sizeof(aVersion)));
EXPECT_STRNE(aVersion, "");
}

View file

@ -11,6 +11,7 @@
TEST(ServerBrowser, PingCache)
{
CTestInfo Info;
Info.m_DeleteTestStorageFilesOnSuccess = true;
auto pConsole = std::unique_ptr<IConsole>(CreateConsole(CFGFLAG_CLIENT));
auto pStorage = std::unique_ptr<IStorage>(Info.CreateTestStorage());
@ -99,6 +100,4 @@ TEST(ServerBrowser, PingCache)
EXPECT_EQ(pEntries[0].m_Ping, 1337);
EXPECT_EQ(pEntries[1].m_Ping, 345);
}
Info.DeleteTestStorageFilesOnSuccess();
}

View file

@ -72,15 +72,11 @@ int TestCollect(const char *pName, int IsDir, int Unused, void *pUser)
return 0;
}
void CTestInfo::DeleteTestStorageFilesOnSuccess()
void TestDeleteTestStorageFiles(const char *pPath)
{
if(::testing::Test::HasFailure())
{
return;
}
std::vector<CTestInfoPath> aEntries;
CTestCollectData Data;
str_copy(Data.m_aCurrentDir, m_aFilename, sizeof(Data.m_aCurrentDir));
str_copy(Data.m_aCurrentDir, pPath, sizeof(Data.m_aCurrentDir));
Data.m_paEntries = &aEntries;
fs_listdir(Data.m_aCurrentDir, TestCollect, 0, &Data);
@ -107,6 +103,14 @@ void CTestInfo::DeleteTestStorageFilesOnSuccess()
}
}
CTestInfo::~CTestInfo()
{
if(!::testing::Test::HasFailure() && m_DeleteTestStorageFilesOnSuccess)
{
TestDeleteTestStorageFiles(m_aFilename);
}
}
int main(int argc, const char **argv)
{
cmdline_fix(&argc, &argv);

View file

@ -7,8 +7,9 @@ class CTestInfo
{
public:
CTestInfo();
~CTestInfo();
IStorage *CreateTestStorage();
void DeleteTestStorageFilesOnSuccess();
bool m_DeleteTestStorageFilesOnSuccess = false;
char m_aFilename[64];
};
#endif // TEST_TEST_H