You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
3.9 KiB
68 lines
3.9 KiB
/* Общий формат опросов, ответов и реакций. Подписанное poll-сообщение неизменяемо. |
|
* single допускает один пункт ИЛИ свой ответ; multiple — пункты и необязательный свой ответ. |
|
* Пустой ответ/набор реакций кодируется нулевой длиной и сохраняется с новым ver. |
|
* Все сетевые/DB API вызываются в uasync; кодеки не зависят от экземпляра. |
|
* JSON-снимки и результаты команд выделяются через u_malloc, освобождаются u_free. */ |
|
#ifndef CHAT_POLL_H |
|
#define CHAT_POLL_H |
|
|
|
#include <stdint.h> |
|
#include <stddef.h> |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
struct UTUN_INSTANCE; |
|
|
|
#define CHAT_POLL_SINGLE 1 |
|
#define CHAT_POLL_MULTIPLE 2 |
|
#define CHAT_POLL_OPTIONS_MAX 32 |
|
#define CHAT_POLL_QUESTION_MAX 512 |
|
#define CHAT_POLL_OPTION_MAX 256 |
|
#define CHAT_POLL_CUSTOM_MAX 1024 |
|
#define CHAT_POLL_WIRE_MAX 2048 |
|
#define CHAT_REACTION_COUNT 16 |
|
#define CHAT_REACTION_SELECTED_MAX 8 |
|
|
|
struct chat_poll { |
|
uint8_t mode, allow_custom_answer, option_count; |
|
char question[CHAT_POLL_QUESTION_MAX + 1]; |
|
char options[CHAT_POLL_OPTIONS_MAX][CHAT_POLL_OPTION_MAX + 1]; |
|
}; |
|
|
|
struct chat_poll_answer { |
|
uint8_t count, choices[CHAT_POLL_OPTIONS_MAX]; |
|
char custom[CHAT_POLL_CUSTOM_MAX + 1]; |
|
}; |
|
|
|
/* Кодеки возвращают длину/0, либо -1. Decode требует точное каноническое представление. */ |
|
int chat_poll_encode(const struct chat_poll* poll, uint8_t* out, size_t capacity); |
|
int chat_poll_decode(const uint8_t* data, size_t len, struct chat_poll* poll); |
|
int chat_answer_encode(const struct chat_poll_answer* answer, uint8_t* out, size_t capacity); |
|
int chat_answer_decode(const uint8_t* data, size_t len, struct chat_poll_answer* answer); |
|
int chat_reactions_encode(const uint8_t* ids, size_t count, uint8_t* out, size_t capacity); |
|
int chat_reactions_decode(const uint8_t* data, size_t len, uint8_t ids[CHAT_REACTION_SELECTED_MAX], size_t* count); |
|
/* Постоянный общий каталог: существующие номера не менять. NULL при неверном номере. */ |
|
const char* chat_reaction_emoji(unsigned id); |
|
/* Структурная проверка data, независимая от наличия исходного сообщения. 0/-1. */ |
|
int chat_feedback_validate_data(uint8_t kind, const uint8_t* data, size_t len); |
|
|
|
/* Публикация подписанного poll: 0/-1, out_id — общий ID сохранённого сообщения. */ |
|
int chat_poll_create(struct UTUN_INSTANCE* inst, const char* channel, const struct chat_poll* poll, uint8_t out_id[32]); |
|
/* Снимок сообщения и результатов: pending, poll, reactions, mine и ответы. 0/-1. */ |
|
int chat_feedback_snapshot(struct UTUN_INSTANCE* inst, const char* channel, const uint8_t message_id[32], char** json); |
|
/* JSON-команды poll_create, vote, react, feedback, reaction_catalog. 0/-1. |
|
* Ошибка возвращает JSON с error; успех — снимок или каталог. |
|
* vote: choices:[0..31], custom:string; пустые значения отменяют голос. |
|
* react: emoji:0..15, on:boolean необязателен (без него переключить), clear:true снимает все. */ |
|
int chat_feedback_command(struct UTUN_INSTANCE* inst, const char* command, char** result); |
|
/* Команда из UI: req и следующая за ней NUL-строка выделены одним блоком через u_malloc. |
|
* Результат возвращается событием CHAT_EVT_FEEDBACK_RESULT и включает request_id. */ |
|
struct chat_feedback_request { struct UTUN_INSTANCE* inst; uint64_t request_id; }; |
|
void chat_feedback_command_trampoline(void* arg); |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
#endif
|
|
|