From db3eb04208859f13108d94d15552b97abbc3aca7 Mon Sep 17 00:00:00 2001 From: TimePath Date: Sat, 7 Apr 2018 22:34:00 +1000 Subject: [PATCH] Menu: add menu<-->client extensions system Disable menu based chat if not supported --- qcsrc/lib/unsafe.qh | 15 +++++- qcsrc/menu/menu.qc | 1 + qcsrc/menu/modules/_mod.inc | 1 + qcsrc/menu/modules/_mod.qh | 1 + qcsrc/menu/modules/chat/commands.qc | 9 ++++ qcsrc/menu/modules/chat/interface.qh | 7 +++ qcsrc/menu/modules/chat/state.qc | 2 +- qcsrc/menu/modules/chat/state.qh | 4 ++ qcsrc/menu/modules/extensions/_mod.inc | 3 ++ qcsrc/menu/modules/extensions/_mod.qh | 3 ++ qcsrc/menu/modules/extensions/commands.qc | 54 ++++++++++++++++++++++ qcsrc/menu/modules/extensions/commands.qh | 1 + qcsrc/menu/modules/extensions/interface.qh | 24 ++++++++++ qcsrc/menu/modules/extensions/state.qc | 26 +++++++++++ qcsrc/menu/modules/extensions/state.qh | 16 +++++++ 15 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 qcsrc/menu/modules/extensions/_mod.inc create mode 100644 qcsrc/menu/modules/extensions/_mod.qh create mode 100644 qcsrc/menu/modules/extensions/commands.qc create mode 100644 qcsrc/menu/modules/extensions/commands.qh create mode 100644 qcsrc/menu/modules/extensions/interface.qh create mode 100644 qcsrc/menu/modules/extensions/state.qc create mode 100644 qcsrc/menu/modules/extensions/state.qh diff --git a/qcsrc/lib/unsafe.qh b/qcsrc/lib/unsafe.qh index 60ad3d88d..5bea6878a 100644 --- a/qcsrc/lib/unsafe.qh +++ b/qcsrc/lib/unsafe.qh @@ -10,8 +10,19 @@ X(float) X(vector) X(entity) X(string) -USING(rawfunc, float(...)); -X(rawfunc) + +USING(func_v, void(...)); +X(func_v) + +USING(func_f, float(...)); +X(func_f) + +USING(func_v_v, void()); +X(func_v_v) + +USING(func_bool_v, void(bool)); +X(func_bool_v) + #undef X #define _strid(s) ITOF(reinterpret_cast(int, s)) diff --git a/qcsrc/menu/menu.qc b/qcsrc/menu/menu.qc index af14e0842..3f2e91e47 100644 --- a/qcsrc/menu/menu.qc +++ b/qcsrc/menu/menu.qc @@ -84,6 +84,7 @@ void m_init() } // needs to be done so early because of the constants they create + static_init_early(); static_init(); static_init_late(); static_init_precache(); diff --git a/qcsrc/menu/modules/_mod.inc b/qcsrc/menu/modules/_mod.inc index 8b11cef8c..3590ec3fe 100644 --- a/qcsrc/menu/modules/_mod.inc +++ b/qcsrc/menu/modules/_mod.inc @@ -1,3 +1,4 @@ // generated file; do not modify #include +#include diff --git a/qcsrc/menu/modules/_mod.qh b/qcsrc/menu/modules/_mod.qh index 026d48278..add806e2e 100644 --- a/qcsrc/menu/modules/_mod.qh +++ b/qcsrc/menu/modules/_mod.qh @@ -1,3 +1,4 @@ // generated file; do not modify #include +#include diff --git a/qcsrc/menu/modules/chat/commands.qc b/qcsrc/menu/modules/chat/commands.qc index 5e4c052a1..b84ef7226 100644 --- a/qcsrc/menu/modules/chat/commands.qc +++ b/qcsrc/menu/modules/chat/commands.qc @@ -41,6 +41,9 @@ GENERIC_COMMAND(commandmode, "input a console command") { case CMD_REQUEST_COMMAND: { + if (!autoextension_chat) { + return; + } string prefix = arguments > 1 ? strcat(substring(command, argv_start_index(1), argv_end_index(-1)), " ") : ""; chat_command = ""; strcpy(chat_text, prefix); @@ -65,6 +68,9 @@ GENERIC_COMMAND(messagemode, "input a chat message to say to everyone") { case CMD_REQUEST_COMMAND: { + if (!autoextension_chat) { + return; + } string prefix = arguments > 1 ? strcat(substring(command, argv_start_index(1), argv_end_index(-1)), " ") : ""; chat_command = "say "; strcpy(chat_text, prefix); @@ -89,6 +95,9 @@ GENERIC_COMMAND(messagemode2, "input a chat message to say to only your team") { case CMD_REQUEST_COMMAND: { + if (!autoextension_chat) { + return; + } string prefix = arguments > 1 ? strcat(substring(command, argv_start_index(1), argv_end_index(-1)), " ") : ""; chat_command = "say_team "; strcpy(chat_text, prefix); diff --git a/qcsrc/menu/modules/chat/interface.qh b/qcsrc/menu/modules/chat/interface.qh index 1760a2ef3..7eb9b5039 100644 --- a/qcsrc/menu/modules/chat/interface.qh +++ b/qcsrc/menu/modules/chat/interface.qh @@ -1,5 +1,12 @@ #pragma once +#include + #include "commands.qh" string autocvar__cl_hook_print; + +STATIC_INIT(extension_chat) +{ + extensions_report("org.xonotic:chat:1"); +} diff --git a/qcsrc/menu/modules/chat/state.qc b/qcsrc/menu/modules/chat/state.qc index 299efbdb5..bd5e717c9 100644 --- a/qcsrc/menu/modules/chat/state.qc +++ b/qcsrc/menu/modules/chat/state.qc @@ -8,7 +8,7 @@ STATIC_INIT(chat_buffer) { } int chat_lines_count() { - return chat_buffer_idx + 1; + return chat_buffer_idx; } string chat_lines_get(int i) { diff --git a/qcsrc/menu/modules/chat/state.qh b/qcsrc/menu/modules/chat/state.qh index 9ca190389..79be06a9e 100644 --- a/qcsrc/menu/modules/chat/state.qh +++ b/qcsrc/menu/modules/chat/state.qh @@ -1,5 +1,7 @@ #pragma once +#include + string chat_command; string chat_text; @@ -8,3 +10,5 @@ int chat_lines_count(); string chat_lines_get(int i); void chat_lines_push(string s); + +AUTOEXTENSION(chat, "org.xonotic:chat:1"); diff --git a/qcsrc/menu/modules/extensions/_mod.inc b/qcsrc/menu/modules/extensions/_mod.inc new file mode 100644 index 000000000..9a5edca19 --- /dev/null +++ b/qcsrc/menu/modules/extensions/_mod.inc @@ -0,0 +1,3 @@ +// generated file; do not modify +#include +#include diff --git a/qcsrc/menu/modules/extensions/_mod.qh b/qcsrc/menu/modules/extensions/_mod.qh new file mode 100644 index 000000000..93581cf20 --- /dev/null +++ b/qcsrc/menu/modules/extensions/_mod.qh @@ -0,0 +1,3 @@ +// generated file; do not modify +#include +#include diff --git a/qcsrc/menu/modules/extensions/commands.qc b/qcsrc/menu/modules/extensions/commands.qc new file mode 100644 index 000000000..77eab7fa4 --- /dev/null +++ b/qcsrc/menu/modules/extensions/commands.qc @@ -0,0 +1,54 @@ +#include "commands.qh" + +#include "state.qh" + +// space separated list of extensions +void extensions_set(string s) +{ + for (int i = 0, n = extensions_count(); i < n; ++i) { + string id = extensions_get_name(i); + void(bool) set = extensions_get_setter(i); + bool enable = strhasword(s, id); + set(enable); + } +} + +GENERIC_COMMAND(_cl_hook_gamestart, "_cl_hook_gamestart") +{ + switch(request) + { + case CMD_REQUEST_COMMAND: + { + string s = substring(command, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)); + localcmd("\nset _cl_hook_gametype ", s, "; _cl_hook_gamestart_stage2\n"); + extensions_set(cvar_string("_cl_extensions")); + cvar_set("_cl_extensions", ""); + return; + } + + default: + case CMD_REQUEST_USAGE: + { + return; + } + } +} + +GENERIC_COMMAND(_cl_extensions, "_cl_extensions") +{ + switch(request) + { + case CMD_REQUEST_COMMAND: + { + string s = substring(command, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)); + extensions_set(s); + return; + } + + default: + case CMD_REQUEST_USAGE: + { + return; + } + } +} diff --git a/qcsrc/menu/modules/extensions/commands.qh b/qcsrc/menu/modules/extensions/commands.qh new file mode 100644 index 000000000..6f70f09be --- /dev/null +++ b/qcsrc/menu/modules/extensions/commands.qh @@ -0,0 +1 @@ +#pragma once diff --git a/qcsrc/menu/modules/extensions/interface.qh b/qcsrc/menu/modules/extensions/interface.qh new file mode 100644 index 000000000..db690ecf3 --- /dev/null +++ b/qcsrc/menu/modules/extensions/interface.qh @@ -0,0 +1,24 @@ +#pragma once + +#ifdef MENUQC +void extensions_register(string id, void(bool) set); +#endif + +#define AUTOEXTENSION(var, id) \ + bool autoextension_##var; \ + void autoextension_##var##_set(bool val) { \ + autoextension_##var = val; \ + } \ + STATIC_INIT(autoextension_##var) \ + { \ + extensions_register(id, autoextension_##var##_set); \ + } + +noref string autocvar__cl_extensions; +STATIC_INIT(extensions) +{ + cvar_set("_cl_extensions", ""); +} + +#define extensions_report(id) \ + cvar_set("_cl_extensions", cons(cvar_string("_cl_extensions"), id)) diff --git a/qcsrc/menu/modules/extensions/state.qc b/qcsrc/menu/modules/extensions/state.qc new file mode 100644 index 000000000..15502812a --- /dev/null +++ b/qcsrc/menu/modules/extensions/state.qc @@ -0,0 +1,26 @@ +#include "state.qh" + +int extensions_buffer; +int extensions_buffer_idx; + +STATIC_INIT_EARLY(extensions_buffer) +{ + extensions_buffer = buf_create(); +} + +int extensions_count() +{ + return extensions_buffer_idx; +} + +string extensions_get(int i, int fld) +{ + return bufstr_get(extensions_buffer, i * _EXTENSIONS_FIELDS + fld); +} + +void extensions_register(string id, void(bool) set) +{ + int i = extensions_buffer_idx++ * _EXTENSIONS_FIELDS; + bufstr_set(extensions_buffer, i + EXTENSIONS_NAME, id); + bufstr_set(extensions_buffer, i + EXTENSIONS_SETTER, ftos(ITOF(reinterpret_cast(int, set)))); +} diff --git a/qcsrc/menu/modules/extensions/state.qh b/qcsrc/menu/modules/extensions/state.qh new file mode 100644 index 000000000..4f2acbddc --- /dev/null +++ b/qcsrc/menu/modules/extensions/state.qh @@ -0,0 +1,16 @@ +#pragma once + +int extensions_count(); + +enum { + EXTENSIONS_NAME, + EXTENSIONS_SETTER, + _EXTENSIONS_FIELDS, +}; + +string extensions_get(int i, int fld); + +#define extensions_get_name(i) extensions_get(i, EXTENSIONS_NAME) + +#define extensions_get_setter(i) reinterpret_cast(func_bool_v, FTOI(stof(extensions_get(i, EXTENSIONS_SETTER)))) + -- 2.39.2