






















MACRO({"first", "second"}) has two arguments isntead of one



MACRO({"first", "second"}) has two arguments isntead of one 







MACRO({"first", "second"}) has two arguments isntead of one MACRO(({"first", "second"})) 








#include <iostream>
using namespace std;
template<typename H, typename ... T> constexpr auto last_of(H const& h, T const&... t)
{
if constexpr (sizeof...(t)) return last_of(t...); else return h;
}
template<typename H, typename ... T> constexpr void A(H const& h, T const&... t)
{
cout << h << " " << last_of(t...) << endl;
if constexpr (sizeof...(t) > 1) A(t...);
}
int main(int, char**)
{
A("r","rescue", "command for ChillerDragon");
A("top","top5", "mess with selfesteem");
A("earrape", "fng only");
}















{"cmd"} also if there is only one command and only work with an initializer list

{}, it was his choice 







#define CHAT_COMMAND(names, params, flags, callback, userdata, help) \
for(const char *pName : names) \
m_pConsole->Register(pName, params, flags, callback, userdata, help);
CHAT_COMMAND({"map"}, "?r[map]", CFGFLAG_CHAT | CFGFLAG_SERVER | CFGFLAG_NONTEEHISTORIC, ConMap, this, "Vote a map by name") (edited)

CHAT_COMMAND({"map", "bar"}, "?r[map]", CFGFLAG_CHAT | CFGFLAG_SERVER | CFGFLAG_NONTEEHISTORIC, ConMap, this, "Vote a map by name")






{"cmd"} also if there is only one command and only work with an initializer list 











#define CHAT_COMMAND(name, params, flags, callback, userdata, help) m_pConsole->Register(name, params, flags, callback, userdata, help);














std::functions so you can pass lambda expressions when registering the command















1






































































MACRO(({"first", "second"})) 










#define CHAT_COMMAND(names, params, flags, callback, userdata, help) \
for(const char *pName : names) \
m_pConsole->Register(pName, params, flags, callback, userdata, help);
CHAT_COMMAND({"map"}, "?r[map]", CFGFLAG_CHAT | CFGFLAG_SERVER | CFGFLAG_NONTEEHISTORIC, ConMap, this, "Vote a map by name") (edited){"map", /* <- this one */ "nomap"} has two arguments isntead of one





gameclient.h include with more specific includes.
Fix storage creation error message not being logged as the logger was initialized after checking for the failed storage creation. However, in this case we want to avoid non-error log messages so the tool's output is only the extracted demo chat, except in error cases.
Rename Process function to ExtractDemoChat and make it static to avoid exporting it.
Use log_error instead of dbg_msg.

ResaveMap.
Ensure reader is closed when writer could not be opened.


























































































































(also it can crash a page) (edited)






































str_comp(..., ...) == 0 || str_comp(..., ...) == 0












ddnet-serverlist-urls.cfg in the same directory as settings_ddnet.cfg and put a url there. https://master1.ddnet.org/ddnet/15/servers.json for example and it should be cached.


ddnet quit
With ddnet-serverlist-urls.cfg
DDNet quit 0.81s user 0.64s system 88% cpu 1.641 total
Without
DDNet quit 0.92s user 0.68s system 31% cpu 5.011 total


IJob::Cancel.

IJob::Cancel. 


curl_global_cleanup























bool IsImportant() with default false or bool IsCancellable() with default true?
bool ShouldWaitBeforeQuitting()? maybe even defaulting to true to opt out of it?












exit_group on Linux











curl_global_cleanup while stuff is still running)














