Advertisement
psycholyzern

Untitled

Oct 10th, 2015
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 52.03 KB | None | 0 0
  1. /*
  2. This file is part of telegram-cli.
  3.  
  4. Telegram-cli is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 2 of the License, or
  7. (at your option) any later version.
  8.  
  9. Telegram-cli is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this telegram-cli. If not, see <http://www.gnu.org/licenses/>.
  16.  
  17. Copyright Vitaly Valtman 2013-2015
  18. */
  19.  
  20. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23.  
  24. #ifdef USE_LUA
  25. #include "lua-tg.h"
  26.  
  27. #include <string.h>
  28. #include <stdlib.h>
  29.  
  30.  
  31. #include <lua.h>
  32. #include <lualib.h>
  33. #include <lauxlib.h>
  34. #ifdef EVENT_V2
  35. #include <event2/event.h>
  36. #else
  37. #include <event.h>
  38. #include "event-old.h"
  39. #endif
  40. lua_State *luaState;
  41.  
  42. //#include "interface.h"
  43. //#include "auto/constants.h"
  44. #include <tgl/tgl.h>
  45. #include "interface.h"
  46.  
  47. #include <assert.h>
  48. extern int verbosity;
  49. extern struct tgl_state *TLS;
  50.  
  51. static int have_file;
  52.  
  53. void print_start (void);
  54. void print_end (void);
  55.  
  56. int ps_lua_pcall (lua_State *l, int a, int b, int c) {
  57. print_start ();
  58. int r = lua_pcall (l, a, b, c);
  59. print_end ();
  60. return r;
  61. }
  62.  
  63. #define my_lua_checkstack(L,x) assert (lua_checkstack (L, x))
  64. void push_user (tgl_peer_t *P);
  65. void push_peer (tgl_peer_id_t id, tgl_peer_t *P);
  66.  
  67. void lua_add_string_field (const char *name, const char *value) {
  68. assert (name && strlen (name));
  69. if (!value || !strlen (value)) { return; }
  70. my_lua_checkstack (luaState, 3);
  71. lua_pushstring (luaState, name);
  72. lua_pushstring (luaState, value);
  73. lua_settable (luaState, -3);
  74. }
  75.  
  76. void lua_add_string_field_arr (int num, const char *value) {
  77. if (!value || !strlen (value)) { return; }
  78. my_lua_checkstack (luaState, 3);
  79. lua_pushnumber (luaState, num);
  80. lua_pushstring (luaState, value);
  81. lua_settable (luaState, -3);
  82. }
  83.  
  84. void lua_add_num_field (const char *name, double value) {
  85. assert (name && strlen (name));
  86. my_lua_checkstack (luaState, 3);
  87. lua_pushstring (luaState, name);
  88. lua_pushnumber (luaState, value);
  89. lua_settable (luaState, -3);
  90. }
  91.  
  92. void push_tgl_peer_type (int x) {
  93. switch (x) {
  94. case TGL_PEER_USER:
  95. lua_pushstring (luaState, "user");
  96. break;
  97. case TGL_PEER_CHAT:
  98. lua_pushstring (luaState, "chat");
  99. break;
  100. case TGL_PEER_ENCR_CHAT:
  101. lua_pushstring (luaState, "encr_chat");
  102. break;
  103. default:
  104. assert (0);
  105. }
  106. }
  107.  
  108. void push_user (tgl_peer_t *P) {
  109. my_lua_checkstack (luaState, 4);
  110. lua_add_string_field ("first_name", P->user.first_name);
  111. lua_add_string_field ("last_name", P->user.last_name);
  112. lua_add_string_field ("real_first_name", P->user.real_first_name);
  113. lua_add_string_field ("real_last_name", P->user.real_last_name);
  114. lua_add_string_field ("phone", P->user.phone);
  115. lua_add_string_field ("username", P->user.username);
  116. if (P->user.access_hash) {
  117. lua_add_num_field ("access_hash", 1);
  118. }
  119. }
  120.  
  121. void push_chat (tgl_peer_t *P) {
  122. my_lua_checkstack (luaState, 4);
  123. assert (P->chat.title);
  124. lua_add_string_field ("title", P->chat.title);
  125. lua_add_num_field ("members_num", P->chat.users_num);
  126. if (P->chat.user_list) {
  127. lua_pushstring (luaState, "members");
  128. lua_newtable (luaState);
  129. int i;
  130. for (i = 0; i < P->chat.users_num; i++) {
  131. lua_pushnumber (luaState, i);
  132. tgl_peer_id_t id = TGL_MK_USER (P->chat.user_list[i].user_id);
  133. push_peer (id, tgl_peer_get (TLS, id));
  134. lua_settable (luaState, -3);
  135. }
  136. lua_settable (luaState, -3);
  137. }
  138. }
  139.  
  140. void push_encr_chat (tgl_peer_t *P) {
  141. my_lua_checkstack (luaState, 4);
  142. lua_pushstring (luaState, "user");
  143. push_peer (TGL_MK_USER (P->encr_chat.user_id), tgl_peer_get (TLS, TGL_MK_USER (P->encr_chat.user_id)));
  144. lua_settable (luaState, -3);
  145. }
  146.  
  147. void push_update_types (unsigned flags) {
  148. my_lua_checkstack (luaState, 4);
  149. lua_newtable (luaState);
  150. int cc = 0;
  151.  
  152.  
  153. if (flags & TGL_UPDATE_CREATED) {
  154. lua_add_string_field_arr (cc++, "created");
  155. }
  156. if (flags & TGL_UPDATE_DELETED) {
  157. lua_add_string_field_arr (cc++, "deleted");
  158. }
  159. if (flags & TGL_UPDATE_PHONE) {
  160. lua_add_string_field_arr (cc++, "phone");
  161. }
  162. if (flags & TGL_UPDATE_CONTACT) {
  163. lua_add_string_field_arr (cc++, "contact");
  164. }
  165. if (flags & TGL_UPDATE_PHOTO) {
  166. lua_add_string_field_arr (cc++, "photo");
  167. }
  168. if (flags & TGL_UPDATE_BLOCKED) {
  169. lua_add_string_field_arr (cc++, "blocked");
  170. }
  171. if (flags & TGL_UPDATE_REAL_NAME) {
  172. lua_add_string_field_arr (cc++, "real_name");
  173. }
  174. if (flags & TGL_UPDATE_NAME) {
  175. lua_add_string_field_arr (cc++, "name");
  176. }
  177. if (flags & TGL_UPDATE_REQUESTED) {
  178. lua_add_string_field_arr (cc++, "requested");
  179. }
  180. if (flags & TGL_UPDATE_WORKING) {
  181. lua_add_string_field_arr (cc++, "working");
  182. }
  183. if (flags & TGL_UPDATE_FLAGS) {
  184. lua_add_string_field_arr (cc++, "flags");
  185. }
  186. if (flags & TGL_UPDATE_TITLE) {
  187. lua_add_string_field_arr (cc++, "title");
  188. }
  189. if (flags & TGL_UPDATE_ADMIN) {
  190. lua_add_string_field_arr (cc++, "admin");
  191. }
  192. if (flags & TGL_UPDATE_MEMBERS) {
  193. lua_add_string_field_arr (cc++, "members");
  194. }
  195. if (flags & TGL_UPDATE_ACCESS_HASH) {
  196. lua_add_string_field_arr (cc++, "access_hash");
  197. }
  198. if (flags & TGL_UPDATE_USERNAME) {
  199. lua_add_string_field_arr (cc++, "username");
  200. }
  201.  
  202. }
  203.  
  204. void push_peer (tgl_peer_id_t id, tgl_peer_t *P) {
  205. lua_newtable (luaState);
  206.  
  207. lua_add_num_field ("id", tgl_get_peer_id (id));
  208. lua_pushstring (luaState, "type");
  209. push_tgl_peer_type (tgl_get_peer_type (id));
  210. lua_settable (luaState, -3);
  211.  
  212.  
  213. if (!P || !(P->flags & TGLPF_CREATED)) {
  214. lua_pushstring (luaState, "print_name");
  215. static char s[100];
  216. switch (tgl_get_peer_type (id)) {
  217. case TGL_PEER_USER:
  218. sprintf (s, "user#%d", tgl_get_peer_id (id));
  219. break;
  220. case TGL_PEER_CHAT:
  221. sprintf (s, "chat#%d", tgl_get_peer_id (id));
  222. break;
  223. case TGL_PEER_ENCR_CHAT:
  224. sprintf (s, "encr_chat#%d", tgl_get_peer_id (id));
  225. break;
  226. default:
  227. assert (0);
  228. }
  229. lua_pushstring (luaState, s);
  230. lua_settable (luaState, -3); // flags
  231.  
  232. return;
  233. }
  234.  
  235. lua_add_string_field ("print_name", P->print_name);
  236. lua_add_num_field ("flags", P->flags);
  237.  
  238. switch (tgl_get_peer_type (id)) {
  239. case TGL_PEER_USER:
  240. push_user (P);
  241. break;
  242. case TGL_PEER_CHAT:
  243. push_chat (P);
  244. break;
  245. case TGL_PEER_ENCR_CHAT:
  246. push_encr_chat (P);
  247. break;
  248. default:
  249. assert (0);
  250. }
  251. }
  252.  
  253. void push_media (struct tgl_message_media *M) {
  254. my_lua_checkstack (luaState, 4);
  255.  
  256. switch (M->type) {
  257. case tgl_message_media_photo:
  258. lua_newtable (luaState);
  259. lua_add_string_field ("type", "photo");
  260. lua_add_string_field ("caption", M->caption);
  261. break;
  262. case tgl_message_media_document:
  263. case tgl_message_media_document_encr:
  264. lua_newtable (luaState);
  265. lua_add_string_field ("type", "document");
  266. break;
  267. case tgl_message_media_unsupported:
  268. lua_newtable (luaState);
  269. lua_add_string_field ("type", "unsupported");
  270. break;
  271. case tgl_message_media_geo:
  272. lua_newtable (luaState);
  273. lua_add_string_field ("type", "geo");
  274. lua_add_num_field ("longitude", M->geo.longitude);
  275. lua_add_num_field ("latitude", M->geo.latitude);
  276. break;
  277. case tgl_message_media_contact:
  278. lua_newtable (luaState);
  279. lua_add_string_field ("type", "contact");
  280. lua_add_string_field ("phone", M->phone);
  281. lua_add_string_field ("first_name", M->first_name);
  282. lua_add_string_field ("last_name", M->last_name);
  283. lua_add_num_field ("user_id", M->user_id);
  284. break;
  285. case tgl_message_media_webpage:
  286. lua_newtable (luaState);
  287. lua_add_string_field ("type", "webpage");
  288. lua_add_string_field ("url", M->webpage->url);
  289. lua_add_string_field ("title", M->webpage->title);
  290. lua_add_string_field ("description", M->webpage->description);
  291. lua_add_string_field ("author", M->webpage->author);
  292. break;
  293. case tgl_message_media_venue:
  294. lua_newtable (luaState);
  295. lua_add_string_field ("type", "venue");
  296. lua_add_num_field ("longitude", M->venue.geo.longitude);
  297. lua_add_num_field ("latitude", M->venue.geo.latitude);
  298. lua_add_string_field ("title", M->venue.title);
  299. lua_add_string_field ("address", M->venue.address);
  300. lua_add_string_field ("provider", M->venue.provider);
  301. lua_add_string_field ("venue_id", M->venue.venue_id);
  302. break;
  303. default:
  304. lua_pushstring (luaState, "???");
  305. }
  306. }
  307.  
  308. void push_service (struct tgl_message *M) {
  309. my_lua_checkstack (luaState, 4);
  310. switch (M->action.type) {
  311. case tgl_message_action_geo_chat_create:
  312. lua_newtable (luaState);
  313. lua_add_string_field ("type", "geo_created");
  314. break;
  315. case tgl_message_action_geo_chat_checkin:
  316. lua_newtable (luaState);
  317. lua_add_string_field ("type", "geo_checkin");
  318. break;
  319. case tgl_message_action_chat_create:
  320. lua_newtable (luaState);
  321. lua_add_string_field ("type", "chat_created");
  322. lua_add_string_field ("title", M->action.title);
  323. break;
  324. case tgl_message_action_chat_edit_title:
  325. lua_newtable (luaState);
  326. lua_add_string_field ("type", "chat_rename");
  327. lua_add_string_field ("title", M->action.title);
  328. break;
  329. case tgl_message_action_chat_edit_photo:
  330. lua_newtable (luaState);
  331. lua_add_string_field ("type", "chat_change_photo");
  332. break;
  333. case tgl_message_action_chat_delete_photo:
  334. lua_newtable (luaState);
  335. lua_add_string_field ("type", "chat_delete_photo");
  336. break;
  337. case tgl_message_action_chat_add_user:
  338. lua_newtable (luaState);
  339. lua_add_string_field ("type", "chat_add_user");
  340.  
  341. lua_pushstring (luaState, "user");
  342. push_peer (tgl_set_peer_id (TGL_PEER_USER, M->action.user), tgl_peer_get (TLS, tgl_set_peer_id (TGL_PEER_USER, M->action.user)));
  343. lua_settable (luaState, -3);
  344. break;
  345. case tgl_message_action_chat_add_user_by_link:
  346. lua_newtable (luaState);
  347. lua_add_string_field ("type", "chat_add_user_link");
  348.  
  349. lua_pushstring (luaState, "link_issuer");
  350. push_peer (tgl_set_peer_id (TGL_PEER_USER, M->action.user), tgl_peer_get (TLS, tgl_set_peer_id (TGL_PEER_USER, M->action.user)));
  351. lua_settable (luaState, -3);
  352. break;
  353. case tgl_message_action_chat_delete_user:
  354. lua_newtable (luaState);
  355. lua_add_string_field ("type", "chat_del_user");
  356.  
  357. lua_pushstring (luaState, "user");
  358. push_peer (tgl_set_peer_id (TGL_PEER_USER, M->action.user), tgl_peer_get (TLS, tgl_set_peer_id (TGL_PEER_USER, M->action.user)));
  359. lua_settable (luaState, -3);
  360. break;
  361. case tgl_message_action_set_message_ttl:
  362. lua_newtable (luaState);
  363. lua_add_string_field ("type", "set_ttl");
  364. lua_add_num_field ("ttl", M->action.ttl);
  365. break;
  366. case tgl_message_action_read_messages:
  367. lua_newtable (luaState);
  368. lua_add_string_field ("type", "read");
  369. lua_add_num_field ("count", M->action.read_cnt);
  370. break;
  371. case tgl_message_action_delete_messages:
  372. lua_newtable (luaState);
  373. lua_add_string_field ("type", "delete");
  374. lua_add_num_field ("count", M->action.delete_cnt);
  375. break;
  376. case tgl_message_action_screenshot_messages:
  377. lua_newtable (luaState);
  378. lua_add_string_field ("type", "screenshot");
  379. lua_add_num_field ("count", M->action.screenshot_cnt);
  380. break;
  381. case tgl_message_action_flush_history:
  382. lua_newtable (luaState);
  383. lua_add_string_field ("type", "flush");
  384. break;
  385. case tgl_message_action_resend:
  386. lua_newtable (luaState);
  387. lua_add_string_field ("type", "resend");
  388. break;
  389. case tgl_message_action_notify_layer:
  390. lua_newtable (luaState);
  391. lua_add_string_field ("type", "set_layer");
  392. lua_add_num_field ("layer", M->action.layer);
  393. break;
  394. case tgl_message_action_typing:
  395. lua_newtable (luaState);
  396. lua_add_string_field ("type", "typing");
  397. break;
  398. case tgl_message_action_noop:
  399. lua_newtable (luaState);
  400. lua_add_string_field ("type", "nop");
  401. break;
  402. case tgl_message_action_request_key:
  403. lua_newtable (luaState);
  404. lua_add_string_field ("type", "request_rekey");
  405. break;
  406. case tgl_message_action_accept_key:
  407. lua_newtable (luaState);
  408. lua_add_string_field ("type", "accept_rekey");
  409. break;
  410. case tgl_message_action_commit_key:
  411. lua_newtable (luaState);
  412. lua_add_string_field ("type", "commit_rekey");
  413. break;
  414. case tgl_message_action_abort_key:
  415. lua_newtable (luaState);
  416. lua_add_string_field ("type", "abort_rekey");
  417. break;
  418. default:
  419. lua_pushstring (luaState, "???");
  420. break;
  421. }
  422. }
  423.  
  424. void push_message (struct tgl_message *M) {
  425. assert (M);
  426. my_lua_checkstack (luaState, 10);
  427. lua_newtable (luaState);
  428.  
  429. static char s[30];
  430. snprintf (s, 30, "%lld", M->id);
  431. lua_add_string_field ("id", s);
  432. if (!(M->flags & TGLMF_CREATED)) { return; }
  433. lua_add_num_field ("flags", M->flags);
  434.  
  435. if (tgl_get_peer_type (M->fwd_from_id)) {
  436. lua_pushstring (luaState, "fwd_from");
  437. push_peer (M->fwd_from_id, tgl_peer_get (TLS, M->fwd_from_id));
  438. lua_settable (luaState, -3); // fwd_from
  439.  
  440. lua_add_num_field ("fwd_date", M->fwd_date);
  441. }
  442.  
  443. if (M->reply_id) {
  444. lua_add_num_field ("reply_id", M->reply_id);
  445. }
  446.  
  447. if (M->flags & TGLMF_MENTION) {
  448. lua_pushstring (luaState, "mention");
  449. lua_pushboolean (luaState, 1);
  450. lua_settable (luaState, -3);
  451. }
  452.  
  453. lua_pushstring (luaState, "from");
  454. push_peer (M->from_id, tgl_peer_get (TLS, M->from_id));
  455. lua_settable (luaState, -3);
  456.  
  457. lua_pushstring (luaState, "to");
  458. push_peer (M->to_id, tgl_peer_get (TLS, M->to_id));
  459. lua_settable (luaState, -3);
  460.  
  461. lua_pushstring (luaState, "out");
  462. lua_pushboolean (luaState, (M->flags & TGLMF_OUT) != 0);
  463. lua_settable (luaState, -3);
  464.  
  465. lua_pushstring (luaState, "unread");
  466. lua_pushboolean (luaState, (M->flags & TGLMF_UNREAD) != 0);
  467. lua_settable (luaState, -3);
  468.  
  469. lua_pushstring (luaState, "date");
  470. lua_pushnumber (luaState, M->date);
  471. lua_settable (luaState, -3);
  472.  
  473. lua_pushstring (luaState, "service");
  474. lua_pushboolean (luaState, (M->flags & TGLMF_SERVICE) != 0);
  475. lua_settable (luaState, -3);
  476.  
  477. if (!(M->flags & TGLMF_SERVICE)) {
  478. if (M->message_len && M->message) {
  479. lua_pushstring (luaState, "text");
  480. lua_pushlstring (luaState, M->message, M->message_len);
  481. lua_settable (luaState, -3);
  482. }
  483. if (M->media.type && M->media.type != tgl_message_media_none) {
  484. lua_pushstring (luaState, "media");
  485. push_media (&M->media);
  486. lua_settable (luaState, -3);
  487. }
  488. } else {
  489. lua_pushstring (luaState, "action");
  490. push_service (M);
  491. lua_settable (luaState, -3);
  492. }
  493. }
  494.  
  495. void lua_binlog_end (void) {
  496. if (!have_file) { return; }
  497. lua_settop (luaState, 0);
  498. //lua_checkstack (luaState, 20);
  499. my_lua_checkstack (luaState, 20);
  500. lua_getglobal (luaState, "on_binlog_replay_end");
  501. assert (lua_gettop (luaState) == 1);
  502.  
  503. int r = ps_lua_pcall (luaState, 0, 0, 0);
  504. if (r) {
  505. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  506. }
  507. }
  508.  
  509. void lua_diff_end (void) {
  510. if (!have_file) { return; }
  511. lua_settop (luaState, 0);
  512. //lua_checkstack (luaState, 20);
  513. my_lua_checkstack (luaState, 20);
  514. lua_getglobal (luaState, "on_get_difference_end");
  515. assert (lua_gettop (luaState) == 1);
  516.  
  517. int r = ps_lua_pcall (luaState, 0, 0, 0);
  518. if (r) {
  519. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  520. }
  521. }
  522.  
  523. void lua_our_id (int id) {
  524. if (!have_file) { return; }
  525. lua_settop (luaState, 0);
  526. //lua_checkstack (luaState, 20);
  527. my_lua_checkstack (luaState, 20);
  528. lua_getglobal (luaState, "on_our_id");
  529. lua_pushnumber (luaState, id);
  530. assert (lua_gettop (luaState) == 2);
  531.  
  532. int r = ps_lua_pcall (luaState, 1, 0, 0);
  533. if (r) {
  534. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  535. }
  536. }
  537.  
  538. void lua_new_msg (struct tgl_message *M) {
  539. if (!have_file) { return; }
  540. lua_settop (luaState, 0);
  541. //lua_checkstack (luaState, 20);
  542. my_lua_checkstack (luaState, 20);
  543. lua_getglobal (luaState, "on_msg_receive");
  544. push_message (M);
  545. assert (lua_gettop (luaState) == 2);
  546.  
  547. int r = ps_lua_pcall (luaState, 1, 0, 0);
  548. if (r) {
  549. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  550. }
  551. }
  552.  
  553. void lua_secret_chat_update (struct tgl_secret_chat *C, unsigned flags) {
  554. if (!have_file) { return; }
  555. lua_settop (luaState, 0);
  556. //lua_checkstack (luaState, 20);
  557. my_lua_checkstack (luaState, 20);
  558. lua_getglobal (luaState, "on_secret_chat_update");
  559. push_peer (C->id, (void *)C);
  560. push_update_types (flags);
  561. assert (lua_gettop (luaState) == 3);
  562.  
  563. int r = ps_lua_pcall (luaState, 2, 0, 0);
  564. if (r) {
  565. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  566. }
  567. }
  568.  
  569. void lua_user_update (struct tgl_user *U, unsigned flags) {
  570. if (!have_file) { return; }
  571. lua_settop (luaState, 0);
  572. //lua_checkstack (luaState, 20);
  573. my_lua_checkstack (luaState, 20);
  574. lua_getglobal (luaState, "on_user_update");
  575. push_peer (U->id, (void *)U);
  576. push_update_types (flags);
  577. assert (lua_gettop (luaState) == 3);
  578.  
  579. int r = ps_lua_pcall (luaState, 2, 0, 0);
  580. if (r) {
  581. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  582. }
  583. }
  584.  
  585. void lua_chat_update (struct tgl_chat *C, unsigned flags) {
  586. if (!have_file) { return; }
  587. lua_settop (luaState, 0);
  588. //lua_checkstack (luaState, 20);
  589. my_lua_checkstack (luaState, 20);
  590. lua_getglobal (luaState, "on_chat_update");
  591. push_peer (C->id, (void *)C);
  592. push_update_types (flags);
  593. assert (lua_gettop (luaState) == 3);
  594.  
  595. int r = ps_lua_pcall (luaState, 2, 0, 0);
  596. if (r) {
  597. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  598. }
  599. }
  600.  
  601. //extern tgl_peer_t *Peers[];
  602. //extern int peer_num;
  603.  
  604. #define MAX_LUA_COMMANDS 1000
  605. void *lua_ptr[MAX_LUA_COMMANDS];
  606. static int pos;
  607.  
  608. static inline tgl_peer_t *get_peer (const char *s) {
  609. return tgl_peer_get_by_name (TLS, s);
  610. }
  611.  
  612. enum lua_query_type {
  613. lq_contact_list,
  614. lq_dialog_list,
  615. lq_msg,
  616. lq_send_typing,
  617. lq_send_typing_abort,
  618. lq_rename_chat,
  619. lq_send_photo,
  620. lq_chat_set_photo,
  621. lq_set_profile_photo,
  622. lq_set_profile_name,
  623. lq_send_video,
  624. lq_send_text,
  625. lq_reply,
  626. lq_fwd,
  627. lq_fwd_media,
  628. lq_load_photo,
  629. lq_load_video_thumb,
  630. lq_load_video,
  631. lq_chat_info,
  632. lq_user_info,
  633. lq_history,
  634. lq_chat_add_user,
  635. lq_chat_del_user,
  636. lq_add_contact,
  637. lq_del_contact,
  638. lq_rename_contact,
  639. lq_search,
  640. lq_global_search,
  641. lq_mark_read,
  642. lq_create_secret_chat,
  643. lq_create_group_chat,
  644. lq_send_audio,
  645. lq_send_document,
  646. lq_send_file,
  647. lq_load_audio,
  648. lq_load_document,
  649. lq_load_document_thumb,
  650. lq_delete_msg,
  651. lq_restore_msg,
  652. lq_accept_secret_chat,
  653. lq_send_contact,
  654. lq_status_online,
  655. lq_status_offline,
  656. lq_send_location,
  657. lq_extf,
  658. lq_import_chat_link
  659. };
  660.  
  661. struct lua_query_extra {
  662. int func;
  663. int param;
  664. };
  665.  
  666. void lua_empty_cb (struct tgl_state *TLSR, void *cb_extra, int success) {
  667. assert (TLSR == TLS);
  668. struct lua_query_extra *cb = cb_extra;
  669. lua_settop (luaState, 0);
  670. //lua_checkstack (luaState, 20);
  671. my_lua_checkstack (luaState, 20);
  672.  
  673. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->func);
  674. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->param);
  675.  
  676. lua_pushnumber (luaState, success);
  677.  
  678. assert (lua_gettop (luaState) == 3);
  679.  
  680. int r = ps_lua_pcall (luaState, 2, 0, 0);
  681.  
  682. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->func);
  683. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->param);
  684.  
  685. if (r) {
  686. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  687. }
  688.  
  689. free (cb);
  690. }
  691.  
  692. void lua_contact_list_cb (struct tgl_state *TLSR, void *cb_extra, int success, int num, struct tgl_user **UL) {
  693. assert (TLSR == TLS);
  694. struct lua_query_extra *cb = cb_extra;
  695. lua_settop (luaState, 0);
  696. //lua_checkstack (luaState, 20);
  697. my_lua_checkstack (luaState, 20);
  698.  
  699. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->func);
  700. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->param);
  701.  
  702. lua_pushnumber (luaState, success);
  703.  
  704. if (success) {
  705. lua_newtable (luaState);
  706. int i;
  707. for (i = 0; i < num; i++) {
  708. lua_pushnumber (luaState, i);
  709. push_peer (UL[i]->id, (void *)UL[i]);
  710. lua_settable (luaState, -3);
  711. }
  712. } else {
  713. lua_pushboolean (luaState, 0);
  714. }
  715.  
  716. assert (lua_gettop (luaState) == 4);
  717.  
  718. int r = ps_lua_pcall (luaState, 3, 0, 0);
  719.  
  720. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->func);
  721. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->param);
  722.  
  723. if (r) {
  724. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  725. }
  726.  
  727. free (cb);
  728. }
  729.  
  730. void lua_dialog_list_cb (struct tgl_state *TLSR, void *cb_extra, int success, int num, tgl_peer_id_t peers[], int msgs[], int unread[]) {
  731. assert (TLSR == TLS);
  732. struct lua_query_extra *cb = cb_extra;
  733. lua_settop (luaState, 0);
  734. //lua_checkstack (luaState, 20);
  735. my_lua_checkstack (luaState, 20);
  736.  
  737. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->func);
  738. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->param);
  739.  
  740. lua_pushnumber (luaState, success);
  741. if (success) {
  742. lua_newtable (luaState);
  743. int i;
  744. for (i = 0; i < num; i++) {
  745. lua_pushnumber (luaState, i);
  746.  
  747. lua_newtable (luaState);
  748.  
  749. lua_pushstring (luaState, "peer");
  750. push_peer (peers[i], tgl_peer_get (TLS, peers[i]));
  751. lua_settable (luaState, -3);
  752.  
  753. struct tgl_message *M = tgl_message_get (TLS, msgs[i]);
  754. if (M && (M->flags & TGLMF_CREATED)) {
  755. lua_pushstring (luaState, "message");
  756. push_message (M);
  757. lua_settable (luaState, -3);
  758. }
  759.  
  760. lua_pushstring (luaState, "unread");
  761. lua_pushnumber (luaState, unread[i]);
  762. lua_settable (luaState, -3);
  763.  
  764. lua_settable (luaState, -3);
  765. }
  766. } else {
  767. lua_pushboolean (luaState, 0);
  768. }
  769. assert (lua_gettop (luaState) == 4);
  770.  
  771.  
  772. int r = ps_lua_pcall (luaState, 3, 0, 0);
  773.  
  774. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->func);
  775. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->param);
  776.  
  777. if (r) {
  778. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  779. }
  780.  
  781. free (cb);
  782. }
  783.  
  784. void lua_msg_cb (struct tgl_state *TLSR, void *cb_extra, int success, struct tgl_message *M) {
  785. assert (TLSR == TLS);
  786. struct lua_query_extra *cb = cb_extra;
  787. lua_settop (luaState, 0);
  788. //lua_checkstack (luaState, 20);
  789. my_lua_checkstack (luaState, 20);
  790.  
  791. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->func);
  792. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->param);
  793.  
  794. lua_pushnumber (luaState, success);
  795.  
  796. if (success && M && (M->flags & TGLMF_CREATED)) {
  797. push_message (M);
  798. } else {
  799. lua_pushboolean (luaState, 0);
  800. }
  801.  
  802. assert (lua_gettop (luaState) == 4);
  803.  
  804. int r = ps_lua_pcall (luaState, 3, 0, 0);
  805.  
  806. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->func);
  807. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->param);
  808.  
  809. if (r) {
  810. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  811. }
  812.  
  813. free (cb);
  814. }
  815.  
  816. void lua_msg_list_cb (struct tgl_state *TLSR, void *cb_extra, int success, int num, struct tgl_message *M[]) {
  817. assert (TLSR == TLS);
  818. struct lua_query_extra *cb = cb_extra;
  819. lua_settop (luaState, 0);
  820. //lua_checkstack (luaState, 20);
  821. my_lua_checkstack (luaState, 20);
  822.  
  823. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->func);
  824. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->param);
  825.  
  826. lua_pushnumber (luaState, success);
  827.  
  828. if (success) {
  829. lua_newtable (luaState);
  830. int i;
  831. for (i = 0; i < num; i++) {
  832. lua_pushnumber (luaState, i);
  833. push_message (M[i]);
  834. lua_settable (luaState, -3);
  835. }
  836. } else {
  837. lua_pushboolean (luaState, 0);
  838. }
  839.  
  840. assert (lua_gettop (luaState) == 4);
  841.  
  842. int r = ps_lua_pcall (luaState, 3, 0, 0);
  843.  
  844. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->func);
  845. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->param);
  846.  
  847. if (r) {
  848. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  849. }
  850.  
  851. free (cb);
  852. }
  853.  
  854. void lua_file_cb (struct tgl_state *TLSR, void *cb_extra, int success, const char *file_name) {
  855. assert (TLSR == TLS);
  856. struct lua_query_extra *cb = cb_extra;
  857. lua_settop (luaState, 0);
  858. //lua_checkstack (luaState, 20);
  859. my_lua_checkstack (luaState, 20);
  860.  
  861. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->func);
  862. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->param);
  863.  
  864. lua_pushnumber (luaState, success);
  865.  
  866. if (success) {
  867. lua_pushstring (luaState, file_name);
  868. } else {
  869. lua_pushboolean (luaState, 0);
  870. }
  871.  
  872. assert (lua_gettop (luaState) == 4);
  873.  
  874. int r = ps_lua_pcall (luaState, 3, 0, 0);
  875.  
  876. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->func);
  877. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->param);
  878.  
  879. if (r) {
  880. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  881. }
  882.  
  883. free (cb);
  884. }
  885.  
  886. void lua_chat_cb (struct tgl_state *TLSR, void *cb_extra, int success, struct tgl_chat *C) {
  887. assert (TLSR == TLS);
  888. struct lua_query_extra *cb = cb_extra;
  889. lua_settop (luaState, 0);
  890. //lua_checkstack (luaState, 20);
  891. my_lua_checkstack (luaState, 20);
  892.  
  893. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->func);
  894. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->param);
  895.  
  896. lua_pushnumber (luaState, success);
  897.  
  898. if (success) {
  899. push_peer (C->id, (void *)C);
  900. } else {
  901. lua_pushboolean (luaState, 0);
  902. }
  903.  
  904. assert (lua_gettop (luaState) == 4);
  905.  
  906. int r = ps_lua_pcall (luaState, 3, 0, 0);
  907.  
  908. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->func);
  909. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->param);
  910.  
  911. if (r) {
  912. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  913. }
  914.  
  915. free (cb);
  916. }
  917.  
  918. void lua_secret_chat_cb (struct tgl_state *TLSR, void *cb_extra, int success, struct tgl_secret_chat *C) {
  919. assert (TLSR == TLS);
  920. struct lua_query_extra *cb = cb_extra;
  921. lua_settop (luaState, 0);
  922. //lua_checkstack (luaState, 20);
  923. my_lua_checkstack (luaState, 20);
  924.  
  925. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->func);
  926. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->param);
  927.  
  928. lua_pushnumber (luaState, success);
  929.  
  930. if (success) {
  931. push_peer (C->id, (void *)C);
  932. } else {
  933. lua_pushboolean (luaState, 0);
  934. }
  935.  
  936. assert (lua_gettop (luaState) == 4);
  937.  
  938. int r = ps_lua_pcall (luaState, 3, 0, 0);
  939.  
  940. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->func);
  941. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->param);
  942.  
  943. if (r) {
  944. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  945. }
  946.  
  947. free (cb);
  948. }
  949.  
  950. void lua_user_cb (struct tgl_state *TLSR, void *cb_extra, int success, struct tgl_user *C) {
  951. assert (TLSR == TLS);
  952. struct lua_query_extra *cb = cb_extra;
  953. lua_settop (luaState, 0);
  954. //lua_checkstack (luaState, 20);
  955. my_lua_checkstack (luaState, 20);
  956.  
  957. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->func);
  958. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->param);
  959.  
  960. lua_pushnumber (luaState, success);
  961.  
  962. if (success) {
  963. push_peer (C->id, (void *)C);
  964. } else {
  965. lua_pushboolean (luaState, 0);
  966. }
  967.  
  968. assert (lua_gettop (luaState) == 4);
  969.  
  970. int r = ps_lua_pcall (luaState, 3, 0, 0);
  971.  
  972. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->func);
  973. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->param);
  974.  
  975. if (r) {
  976. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  977. }
  978.  
  979. free (cb);
  980. }
  981.  
  982. void lua_str_cb (struct tgl_state *TLSR, void *cb_extra, int success, const char *data) {
  983. assert (TLSR == TLS);
  984. struct lua_query_extra *cb = cb_extra;
  985. lua_settop (luaState, 0);
  986. //lua_checkstack (luaState, 20);
  987. my_lua_checkstack (luaState, 20);
  988.  
  989. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->func);
  990. lua_rawgeti (luaState, LUA_REGISTRYINDEX, cb->param);
  991.  
  992. lua_pushnumber (luaState, success);
  993.  
  994. if (success) {
  995. lua_pushstring (luaState, data);
  996. } else {
  997. lua_pushboolean (luaState, 0);
  998. }
  999.  
  1000. assert (lua_gettop (luaState) == 4);
  1001.  
  1002. int r = ps_lua_pcall (luaState, 3, 0, 0);
  1003.  
  1004. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->func);
  1005. luaL_unref (luaState, LUA_REGISTRYINDEX, cb->param);
  1006.  
  1007. if (r) {
  1008. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  1009. }
  1010.  
  1011. free (cb);
  1012. }
  1013.  
  1014. void lua_do_all (void) {
  1015. int p = 0;
  1016. while (p < pos) {
  1017. int l = (long)lua_ptr[p ++];
  1018. assert (p + l + 1 <= pos);
  1019. enum lua_query_type f = (long)lua_ptr[p ++];
  1020. struct tgl_message *M;
  1021. char *s, *s1, *s2, *s3;
  1022. switch (f) {
  1023. case lq_contact_list:
  1024. tgl_do_update_contact_list (TLS, lua_contact_list_cb, lua_ptr[p ++]);
  1025. break;
  1026. case lq_dialog_list:
  1027. tgl_do_get_dialog_list (TLS, 100, 0, lua_dialog_list_cb, lua_ptr[p ++]);
  1028. break;
  1029. case lq_msg:
  1030. tgl_do_send_message (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], strlen (lua_ptr[p + 2]), 0, NULL, lua_msg_cb, lua_ptr[p]);
  1031. free (lua_ptr[p + 2]);
  1032. p += 3;
  1033. break;
  1034. case lq_send_typing:
  1035. tgl_do_send_typing (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, tgl_typing_typing, lua_empty_cb, lua_ptr[p]);
  1036. p += 2;
  1037. break;
  1038. case lq_send_typing_abort:
  1039. tgl_do_send_typing (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, tgl_typing_cancel, lua_empty_cb, lua_ptr[p]);
  1040. p += 2;
  1041. break;
  1042. case lq_rename_chat:
  1043. tgl_do_rename_chat (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], strlen (lua_ptr[p + 2]), lua_empty_cb, lua_ptr[p]);
  1044. free (lua_ptr[p + 2]);
  1045. p += 3;
  1046. break;
  1047. case lq_send_photo:
  1048. tgl_do_send_document (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], NULL, 0, TGL_SEND_MSG_FLAG_DOCUMENT_PHOTO, lua_msg_cb, lua_ptr[p]);
  1049. free (lua_ptr[p + 2]);
  1050. p += 3;
  1051. break;
  1052. case lq_send_video:
  1053. tgl_do_send_document (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], NULL, 0, TGL_SEND_MSG_FLAG_DOCUMENT_VIDEO, lua_msg_cb, lua_ptr[p]);
  1054. free (lua_ptr[p + 2]);
  1055. p += 3;
  1056. break;
  1057. case lq_send_audio:
  1058. tgl_do_send_document (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], NULL, 0, TGL_SEND_MSG_FLAG_DOCUMENT_AUDIO, lua_msg_cb, lua_ptr[p]);
  1059. free (lua_ptr[p + 2]);
  1060. p += 3;
  1061. break;
  1062. case lq_send_document:
  1063. tgl_do_send_document (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], NULL, 0, 0, lua_msg_cb, lua_ptr[p]);
  1064. free (lua_ptr[p + 2]);
  1065. p += 3;
  1066. break;
  1067. case lq_send_file:
  1068. tgl_do_send_document (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], NULL, 0, TGL_SEND_MSG_FLAG_DOCUMENT_AUTO, lua_msg_cb, lua_ptr[p]);
  1069. free (lua_ptr[p + 2]);
  1070. p += 3;
  1071. break;
  1072. case lq_send_text:
  1073. tgl_do_send_text (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], 0, lua_msg_cb, lua_ptr[p]);
  1074. free (lua_ptr[p + 2]);
  1075. p += 3;
  1076. break;
  1077. case lq_chat_set_photo:
  1078. tgl_do_set_chat_photo (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], lua_empty_cb, lua_ptr[p]);
  1079. free (lua_ptr[p + 2]);
  1080. p += 3;
  1081. break;
  1082. case lq_load_photo:
  1083. case lq_load_video:
  1084. case lq_load_audio:
  1085. case lq_load_document:
  1086. M = lua_ptr[p + 1];
  1087. if (!M || (M->media.type != tgl_message_media_photo && M->media.type != tgl_message_media_document && M->media.type != tgl_message_media_document_encr)) {
  1088. lua_file_cb (TLS, lua_ptr[p], 0, 0);
  1089. } else {
  1090. if (M->media.type == tgl_message_media_photo) {
  1091. assert (M->media.photo);
  1092. tgl_do_load_photo (TLS, M->media.photo, lua_file_cb, lua_ptr[p]);
  1093. } else if (M->media.type == tgl_message_media_document) {
  1094. assert (M->media.document);
  1095. tgl_do_load_document (TLS, M->media.document, lua_file_cb, lua_ptr[p]);
  1096. } else {
  1097. tgl_do_load_encr_document (TLS, M->media.encr_document, lua_file_cb, lua_ptr[p]);
  1098. }
  1099. }
  1100. p += 2;
  1101. break;
  1102. case lq_load_video_thumb:
  1103. case lq_load_document_thumb:
  1104. M = lua_ptr[p + 1];
  1105. if (!M || (M->media.type != tgl_message_media_document)) {
  1106. lua_file_cb (TLS, lua_ptr[p], 0, 0);
  1107. } else {
  1108. tgl_do_load_document_thumb (TLS, M->media.document, lua_file_cb, lua_ptr[p]);
  1109. }
  1110. p += 2;
  1111. break;
  1112. case lq_reply:
  1113. tgl_do_reply_message (TLS, &lua_ptr[p + 1].msg_id, LUA_STR_ARG (p + 2), 0, lua_msg_cb, lua_ptr[p].ptr);
  1114. p += 3;
  1115. break;
  1116. case lq_fwd:
  1117. tgl_do_forward_message (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, ((struct tgl_message *)lua_ptr[p + 2])->id, 0, lua_msg_cb, lua_ptr[p]);
  1118. p += 3;
  1119. break;
  1120. case lq_fwd_media:
  1121. tgl_do_forward_media (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, ((struct tgl_message *)lua_ptr[p + 2])->id, 0, lua_msg_cb, lua_ptr[p]);
  1122. p += 3;
  1123. break;
  1124. case lq_chat_info:
  1125. tgl_do_get_chat_info (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, 0, lua_chat_cb, lua_ptr[p]);
  1126. p += 2;
  1127. break;
  1128. case lq_user_info:
  1129. tgl_do_get_user_info (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, 0, lua_user_cb, lua_ptr[p]);
  1130. p += 2;
  1131. break;
  1132. case lq_history:
  1133. tgl_do_get_history (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, 0, (long)lua_ptr[p + 2], 0, lua_msg_list_cb, lua_ptr[p]);
  1134. p += 3;
  1135. break;
  1136. case lq_chat_add_user:
  1137. tgl_do_add_user_to_chat (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, ((tgl_peer_t *)lua_ptr[p + 2])->id, 10, lua_empty_cb, lua_ptr[p]);
  1138. p += 3;
  1139. break;
  1140. case lq_chat_del_user:
  1141. tgl_do_del_user_from_chat (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, ((tgl_peer_t *)lua_ptr[p + 2])->id, lua_empty_cb, lua_ptr[p]);
  1142. p += 3;
  1143. break;
  1144. case lq_add_contact:
  1145. s1 = lua_ptr[p + 1];
  1146. s2 = lua_ptr[p + 2];
  1147. s3 = lua_ptr[p + 3];
  1148. tgl_do_add_contact (TLS, s1, strlen (s1), s2, strlen (s2), s3, strlen (s3), 0, lua_contact_list_cb, lua_ptr[p]);
  1149. free (s1);
  1150. free (s2);
  1151. free (s3);
  1152. p += 4;
  1153. break;
  1154. case lq_del_contact:
  1155. tgl_do_del_contact (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_empty_cb, lua_ptr[p]);
  1156. p += 2;
  1157. break;
  1158. case lq_rename_contact:
  1159. s1 = lua_ptr[p + 1];
  1160. s2 = lua_ptr[p + 2];
  1161. s3 = lua_ptr[p + 3];
  1162. tgl_do_add_contact (TLS, s1, strlen (s1), s2, strlen (s2), s3, strlen (s3), 1, lua_contact_list_cb, lua_ptr[p]);
  1163. free (s1);
  1164. free (s2);
  1165. free (s3);
  1166. p += 4;
  1167. break;
  1168. case lq_search:
  1169. s = lua_ptr[p + 2];
  1170. tgl_do_msg_search (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, 0, 0, 40, 0, s, strlen (s), lua_msg_list_cb, lua_ptr[p]);
  1171. free (s);
  1172. p += 3;
  1173. break;
  1174. case lq_global_search:
  1175. s = lua_ptr[p + 1];
  1176. tgl_do_msg_search (TLS, tgl_set_peer_id (TGL_PEER_UNKNOWN, 0), 0, 0, 40, 0, s, strlen (s), lua_msg_list_cb, lua_ptr[p]);
  1177. free (s);
  1178. p += 2;
  1179. break;
  1180. case lq_mark_read:
  1181. tgl_do_mark_read (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_empty_cb, lua_ptr[p]);
  1182. p += 2;
  1183. break;
  1184. case lq_set_profile_photo:
  1185. s = lua_ptr[p + 1];
  1186. tgl_do_set_profile_photo (TLS, s, lua_empty_cb, lua_ptr[p]);
  1187. free (s);
  1188. p += 2;
  1189. break;
  1190. case lq_set_profile_name:
  1191. s1 = lua_ptr[p + 1];
  1192. s2 = lua_ptr[p + 1];
  1193. tgl_do_set_profile_name (TLS, s1, strlen (s1), s2, strlen (s2), lua_user_cb, lua_ptr[p]);
  1194. free (s1);
  1195. free (s2);
  1196. p += 3;
  1197. break;
  1198. case lq_create_secret_chat:
  1199. tgl_do_create_secret_chat (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_secret_chat_cb, lua_ptr[p]);
  1200. p += 2;
  1201. break;
  1202. case lq_create_group_chat:
  1203. s = lua_ptr[p + 2];
  1204. tgl_do_create_group_chat (TLS, 1, &((tgl_peer_t *)lua_ptr[p + 1])->id, s, strlen (s), lua_empty_cb, lua_ptr[p]);
  1205. free (s);
  1206. p += 3;
  1207. break;
  1208. case lq_delete_msg:
  1209. tgl_do_delete_msg (TLS, ((struct tgl_message *)lua_ptr[p + 1])->id, lua_empty_cb, lua_ptr[p]);
  1210. p += 2;
  1211. break;
  1212. case lq_restore_msg:
  1213. tgl_do_delete_msg (TLS, (long)lua_ptr[p + 1], lua_empty_cb, lua_ptr[p]);
  1214. p += 2;
  1215. break;
  1216. case lq_accept_secret_chat:
  1217. tgl_do_accept_encr_chat_request (TLS, lua_ptr[p + 1], lua_secret_chat_cb, lua_ptr[p]);
  1218. p += 2;
  1219. break;
  1220. case lq_send_contact:
  1221. s1 = lua_ptr[p + 2];
  1222. s2 = lua_ptr[p + 3];
  1223. s3 = lua_ptr[p + 4];
  1224. tgl_do_send_contact (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id, s1, strlen (s1), s2, strlen (s2), s3, strlen (s3), 0, lua_msg_cb, lua_ptr[p]);
  1225. free (s1);
  1226. free (s2);
  1227. free (s3);
  1228. p += 5;
  1229. break;
  1230. case lq_status_online:
  1231. tgl_do_update_status (TLS, 1, lua_empty_cb, lua_ptr[p]);
  1232. p ++;
  1233. break;
  1234. case lq_status_offline:
  1235. tgl_do_update_status (TLS, 0, lua_empty_cb, lua_ptr[p]);
  1236. p ++;
  1237. break;
  1238. case lq_extf:
  1239. s = lua_ptr[p + 1];
  1240. tgl_do_send_extf (TLS, s, strlen (s), lua_str_cb, lua_ptr[p]);
  1241. free (s);
  1242. p += 2;
  1243. break;
  1244. case lq_import_chat_link:
  1245. s = lua_ptr[p + 1];
  1246. tgl_do_import_chat_link (TLS, s, strlen (s), lua_empty_cb, lua_ptr[p]);
  1247. free (s);
  1248. p += 2;
  1249. break;
  1250. case lq_send_location:
  1251. if (sizeof (void *) == 4) {
  1252. tgl_do_send_location (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id , *(float *)(lua_ptr + p + 2), *(float *)(lua_ptr + p + 3), 0, lua_msg_cb, lua_ptr[p]);
  1253. } else {
  1254. tgl_do_send_location (TLS, ((tgl_peer_t *)lua_ptr[p + 1])->id , *(double *)(lua_ptr + p + 2), *(double *)(lua_ptr + p + 3), 0, lua_msg_cb, lua_ptr[p]);
  1255. }
  1256. p += 4;
  1257. break;
  1258. /*
  1259. lq_delete_msg,
  1260. lq_restore_msg,
  1261. case 0:
  1262. tgl_do_send_message (((tgl_peer_t *)lua_ptr[p])->id, lua_ptr[p + 1], strlen (lua_ptr[p + 1]), 0, 0);
  1263. free (lua_ptr[p + 1]);
  1264. p += 2;
  1265. break;
  1266. case 1:
  1267. tgl_do_forward_message (((tgl_peer_t *)lua_ptr[p])->id, (long)lua_ptr[p + 1], 0, 0);
  1268. p += 2;
  1269. break;
  1270. case 2:
  1271. tgl_do_mark_read (((tgl_peer_t *)lua_ptr[p])->id, 0, 0);
  1272. p += 1;
  1273. break;*/
  1274. default:
  1275. assert (0);
  1276. }
  1277. }
  1278. pos = 0;
  1279. }
  1280.  
  1281.  
  1282. enum lua_function_param {
  1283. lfp_none,
  1284. lfp_peer,
  1285. lfp_chat,
  1286. lfp_user,
  1287. lfp_secret_chat,
  1288. lfp_string,
  1289. lfp_number,
  1290. lfp_positive_number,
  1291. lfp_nonnegative_number,
  1292. lfp_msg,
  1293. lfp_double
  1294. };
  1295.  
  1296. struct lua_function {
  1297. char *name;
  1298. enum lua_query_type type;
  1299. enum lua_function_param params[10];
  1300. };
  1301.  
  1302. struct lua_function functions[] = {
  1303. {"get_contact_list", lq_contact_list, { lfp_none }},
  1304. {"get_dialog_list", lq_dialog_list, { lfp_none }},
  1305. {"rename_chat", lq_rename_chat, { lfp_chat, lfp_string, lfp_none }},
  1306. {"send_msg", lq_msg, { lfp_peer, lfp_string, lfp_none }},
  1307. {"send_typing", lq_send_typing, { lfp_peer, lfp_none }},
  1308. {"send_typing_abort", lq_send_typing_abort, { lfp_peer, lfp_none }},
  1309. {"send_photo", lq_send_photo, { lfp_peer, lfp_string, lfp_none }},
  1310. {"send_video", lq_send_video, { lfp_peer, lfp_string, lfp_none }},
  1311. {"send_audio", lq_send_audio, { lfp_peer, lfp_string, lfp_none }},
  1312. {"send_document", lq_send_document, { lfp_peer, lfp_string, lfp_none }},
  1313. {"send_file", lq_send_file, { lfp_peer, lfp_string, lfp_none }},
  1314. {"send_text", lq_send_text, { lfp_peer, lfp_string, lfp_none }},
  1315. {"chat_set_photo", lq_chat_set_photo, { lfp_chat, lfp_string, lfp_none }},
  1316. {"load_photo", lq_load_photo, { lfp_msg, lfp_none }},
  1317. {"load_video", lq_load_video, { lfp_msg, lfp_none }},
  1318. {"load_video_thumb", lq_load_video_thumb, { lfp_msg, lfp_none }},
  1319. {"load_audio", lq_load_audio, { lfp_msg, lfp_none }},
  1320. {"load_document", lq_load_document, { lfp_msg, lfp_none }},
  1321. {"load_document_thumb", lq_load_document_thumb, { lfp_msg, lfp_none }},
  1322. {"reply_msg", lq_reply, { lfp_msg, lfp_string, lfp_none }},
  1323. {"fwd_msg", lq_fwd, { lfp_peer, lfp_msg, lfp_none }},
  1324. {"fwd_media", lq_fwd_media, { lfp_peer, lfp_msg, lfp_none }},
  1325. {"chat_info", lq_chat_info, { lfp_chat, lfp_none }},
  1326. {"user_info", lq_user_info, { lfp_user, lfp_none }},
  1327. {"get_history", lq_history, { lfp_peer, lfp_nonnegative_number, lfp_none }},
  1328. {"chat_add_user", lq_chat_add_user, { lfp_chat, lfp_user, lfp_none }},
  1329. {"chat_del_user", lq_chat_del_user, { lfp_chat, lfp_user, lfp_none }},
  1330. {"add_contact", lq_add_contact, { lfp_string, lfp_string, lfp_string, lfp_none }},
  1331. {"del_contact", lq_del_contact, { lfp_user, lfp_none }},
  1332. {"rename_contact", lq_rename_contact, { lfp_string, lfp_string, lfp_string, lfp_none }},
  1333. {"msg_search", lq_search, { lfp_peer, lfp_string, lfp_none }},
  1334. {"msg_global_search", lq_global_search, { lfp_string, lfp_none }},
  1335. {"mark_read", lq_mark_read, { lfp_peer, lfp_none }},
  1336. {"set_profile_photo", lq_set_profile_photo, { lfp_string, lfp_none }},
  1337. {"set_profile_name", lq_set_profile_name, { lfp_string, lfp_none }},
  1338. {"create_secret_chat", lq_create_secret_chat, { lfp_user, lfp_none }},
  1339. {"create_group_chat", lq_create_group_chat, { lfp_user, lfp_string, lfp_none }},
  1340. {"delete_msg", lq_delete_msg, { lfp_msg, lfp_none }},
  1341. {"restore_msg", lq_restore_msg, { lfp_positive_number, lfp_none }},
  1342. {"accept_secret_chat", lq_accept_secret_chat, { lfp_secret_chat, lfp_none }},
  1343. {"send_contact", lq_send_contact, { lfp_peer, lfp_string, lfp_string, lfp_string, lfp_none }},
  1344. {"status_online", lq_status_online, { lfp_none }},
  1345. {"status_offline", lq_status_offline, { lfp_none }},
  1346. {"send_location", lq_send_location, { lfp_peer, lfp_double, lfp_double, lfp_none }},
  1347. {"ext_function", lq_extf, { lfp_string, lfp_none }},
  1348. {"import_chat_link", lq_import_chat_link, { lfp_string, lfp_none }},
  1349. { 0, 0, { lfp_none}}
  1350. };
  1351.  
  1352. static int parse_lua_function (lua_State *L, struct lua_function *F) {
  1353. int p = 0;
  1354. while (F->params[p] != lfp_none) { p ++; }
  1355. if (lua_gettop (L) != p + 2) {
  1356. lua_pushboolean (L, 0);
  1357. return 1;
  1358. }
  1359.  
  1360. int a1 = luaL_ref (L, LUA_REGISTRYINDEX);
  1361. int a2 = luaL_ref (L, LUA_REGISTRYINDEX);
  1362.  
  1363. struct lua_query_extra *e = malloc (sizeof (*e));
  1364. assert (e);
  1365. e->func = a2;
  1366. e->param = a1;
  1367.  
  1368. assert (pos + 3 + p < MAX_LUA_COMMANDS);
  1369.  
  1370. lua_ptr[pos ++] = (void *)(long)(p + 1);
  1371. lua_ptr[pos ++] = (void *)(long)F->type;
  1372. lua_ptr[pos ++] = e;
  1373.  
  1374. int sp = p;
  1375. int ok = 1;
  1376. int cc = 0;
  1377. while (p > 0) {
  1378. p --;
  1379. cc ++;
  1380. const char *s;
  1381. tgl_peer_t *P;
  1382. long long num;
  1383. double dval;
  1384. struct tgl_message *M;
  1385. switch (F->params[p]) {
  1386. case lfp_none:
  1387. assert (0);
  1388. break;
  1389. case lfp_peer:
  1390. case lfp_user:
  1391. case lfp_chat:
  1392. case lfp_secret_chat:
  1393. s = lua_tostring (L, -cc);
  1394. if (!s) {
  1395. ok = 0;
  1396. break;
  1397. }
  1398. if (sscanf (s, "user#id%lld", &num) == 1 && num > 0) {
  1399. tgl_insert_empty_user (TLS, num);
  1400. P = tgl_peer_get (TLS, TGL_MK_USER (num));
  1401. } else if (sscanf (s, "chat#id%lld", &num) == 1 && num > 0) {
  1402. tgl_insert_empty_chat (TLS, num);
  1403. P = tgl_peer_get (TLS, TGL_MK_CHAT (num));
  1404. } else if (sscanf (s, "user#%lld", &num) == 1 && num > 0) {
  1405. tgl_insert_empty_user (TLS, num);
  1406. P = tgl_peer_get (TLS, TGL_MK_USER (num));
  1407. } else if (sscanf (s, "chat#%lld", &num) == 1 && num > 0) {
  1408. tgl_insert_empty_chat (TLS, num);
  1409. P = tgl_peer_get (TLS, TGL_MK_CHAT (num));
  1410. } else {
  1411. P = get_peer (s);
  1412. }
  1413. if (!P/* || !(P->flags & FLAG_CREATED)*/) {
  1414. ok = 0;
  1415. break;
  1416. }
  1417. if (F->params[p] != lfp_peer) {
  1418. if ((tgl_get_peer_type (P->id) == TGL_PEER_USER && F->params[p] != lfp_user) ||
  1419. (tgl_get_peer_type (P->id) == TGL_PEER_CHAT && F->params[p] != lfp_chat) ||
  1420. (tgl_get_peer_type (P->id) == TGL_PEER_ENCR_CHAT && F->params[p] != lfp_secret_chat)) {
  1421. ok = 0;
  1422. break;
  1423. }
  1424. }
  1425. lua_ptr[pos + p] = P;
  1426. break;
  1427.  
  1428. case lfp_string:
  1429. s = lua_tostring (L, -cc);
  1430. if (!s) {
  1431. ok = 0;
  1432. break;
  1433. }
  1434. lua_ptr[pos + p] = (void *)s;
  1435. break;
  1436.  
  1437. case lfp_number:
  1438. num = lua_tonumber (L, -cc);
  1439.  
  1440. lua_ptr[pos + p] = (void *)(long)num;
  1441. break;
  1442.  
  1443. case lfp_double:
  1444. dval = lua_tonumber (L, -cc);
  1445.  
  1446. if (sizeof (void *) == 4) {
  1447. *(float *)(lua_ptr + pos + p) = dval;
  1448. } else {
  1449. assert (sizeof (void *) >= 8);
  1450. *(double *)(lua_ptr + pos + p) = dval;
  1451. }
  1452. break;
  1453.  
  1454. case lfp_positive_number:
  1455. num = lua_tonumber (L, -cc);
  1456. if (num <= 0) {
  1457. ok = 0;
  1458. break;
  1459. }
  1460.  
  1461. lua_ptr[pos + p] = (void *)(long)num;
  1462. break;
  1463.  
  1464. case lfp_nonnegative_number:
  1465. num = lua_tonumber (L, -cc);
  1466. if (num < 0) {
  1467. ok = 0;
  1468. break;
  1469. }
  1470.  
  1471. lua_ptr[pos + p] = (void *)(long)num;
  1472. break;
  1473.  
  1474. case lfp_msg:
  1475. s = lua_tostring (L, -cc);
  1476. if (!s || !strlen (s)) {
  1477. ok = 0;
  1478. break;
  1479. }
  1480.  
  1481. num = atoll (s);
  1482.  
  1483. M = tgl_message_get (TLS, num);
  1484.  
  1485. if (!M || !(M->flags & TGLMF_CREATED)) {
  1486. ok = 0;
  1487. break;
  1488. }
  1489.  
  1490. lua_ptr[pos + p] = M;
  1491. break;
  1492.  
  1493. default:
  1494. assert (0);
  1495. }
  1496. }
  1497. if (!ok) {
  1498. luaL_unref (luaState, LUA_REGISTRYINDEX, a1);
  1499. luaL_unref (luaState, LUA_REGISTRYINDEX, a2);
  1500. free (e);
  1501. pos -= 3;
  1502. lua_pushboolean (L, 0);
  1503. return 1;
  1504. }
  1505.  
  1506. for (p = 0; p < sp; p++) {
  1507. if (F->params[p] == lfp_string) {
  1508. lua_ptr[pos + p] = strdup (lua_ptr[pos + p]);
  1509. }
  1510. }
  1511. pos += p;
  1512.  
  1513. lua_pushboolean (L, 1);
  1514. return 1;
  1515. }
  1516.  
  1517.  
  1518. static void lua_postpone_alarm (evutil_socket_t fd, short what, void *arg) {
  1519. int *t = arg;
  1520.  
  1521. lua_settop (luaState, 0);
  1522. //lua_checkstack (luaState, 20);
  1523. my_lua_checkstack (luaState, 20);
  1524.  
  1525. lua_rawgeti (luaState, LUA_REGISTRYINDEX, t[1]);
  1526. lua_rawgeti (luaState, LUA_REGISTRYINDEX, t[0]);
  1527. assert (lua_gettop (luaState) == 2);
  1528.  
  1529. int r = ps_lua_pcall (luaState, 1, 0, 0);
  1530.  
  1531. luaL_unref (luaState, LUA_REGISTRYINDEX, t[0]);
  1532. luaL_unref (luaState, LUA_REGISTRYINDEX, t[1]);
  1533.  
  1534. if (r) {
  1535. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  1536. }
  1537.  
  1538. }
  1539.  
  1540. static int postpone_from_lua (lua_State *L) {
  1541. int n = lua_gettop (L);
  1542. if (n != 3) {
  1543. lua_pushboolean (L, 0);
  1544. return 1;
  1545. }
  1546.  
  1547. double timeout = lua_tonumber (L, -1);
  1548. if (timeout < 0) {
  1549. lua_pushboolean (L, 0);
  1550. return 1;
  1551. }
  1552.  
  1553. lua_pop (L, 1);
  1554. int a1 = luaL_ref (L, LUA_REGISTRYINDEX);
  1555. int a2 = luaL_ref (L, LUA_REGISTRYINDEX);
  1556.  
  1557.  
  1558. int *t = malloc (16);
  1559. assert (t);
  1560. struct event *ev = evtimer_new (TLS->ev_base, lua_postpone_alarm, t);
  1561. t[0] = a1;
  1562. t[1] = a2;
  1563. *(void **)(t + 2) = ev;
  1564.  
  1565. struct timeval ts= {
  1566. .tv_sec = (long)timeout,
  1567. .tv_usec = (timeout - ((long)timeout)) * 1000000
  1568. };
  1569. event_add (ev, &ts);
  1570.  
  1571. lua_pushboolean (L, 1);
  1572. return 1;
  1573. }
  1574.  
  1575. extern int safe_quit;
  1576. static int safe_quit_from_lua (lua_State *L) {
  1577. int n = lua_gettop (L);
  1578. if (n != 0) {
  1579. lua_pushboolean (L, 0);
  1580. return 1;
  1581. }
  1582. safe_quit = 1;
  1583.  
  1584. lua_pushboolean (L, 1);
  1585. return 1;
  1586. }
  1587.  
  1588. static int universal_from_lua (lua_State *L) {
  1589. const char *s = lua_tostring(L, lua_upvalueindex(1));
  1590. if (!s) {
  1591. lua_pushboolean (L, 0);
  1592. return 1;
  1593. }
  1594. int i = 0;
  1595. while (functions[i].name) {
  1596. if (!strcmp (functions[i].name, s)) {
  1597. return parse_lua_function (L, &functions[i]);
  1598. }
  1599. i ++;
  1600. }
  1601. lua_pushboolean (L, 0);
  1602. return 1;
  1603. }
  1604.  
  1605.  
  1606. static void my_lua_register (lua_State *L, const char *name, lua_CFunction f) {
  1607. lua_pushstring(L, name);
  1608. lua_pushcclosure(L, f, 1);
  1609. lua_setglobal(L, name);
  1610. }
  1611.  
  1612. enum command_argument {
  1613. ca_none,
  1614. ca_user,
  1615. ca_chat,
  1616. ca_secret_chat,
  1617. ca_peer,
  1618. ca_file_name,
  1619. ca_file_name_end,
  1620. ca_period,
  1621. ca_number,
  1622. ca_double,
  1623. ca_string_end,
  1624. ca_string,
  1625. ca_modifier,
  1626. ca_command,
  1627. ca_extf,
  1628.  
  1629.  
  1630. ca_optional = 256
  1631. };
  1632.  
  1633.  
  1634. struct arg {
  1635. int flags;
  1636. struct {
  1637. tgl_peer_t *P;
  1638. struct tgl_message *M;
  1639. char *str;
  1640. long long num;
  1641. double dval;
  1642. };
  1643. };
  1644.  
  1645. struct in_ev;
  1646. struct command {
  1647. char *name;
  1648. enum command_argument args[10];
  1649. void (*fun)(struct command *command, int arg_num, struct arg args[], struct in_ev *ev);
  1650. char *desc;
  1651. void *arg;
  1652. };
  1653.  
  1654. #define NOT_FOUND (int)0x80000000
  1655.  
  1656. static void do_interface_from_lua (struct command *command, int arg_num, struct arg args[], struct in_ev *ev) {
  1657. lua_settop (luaState, 0);
  1658. my_lua_checkstack (luaState, 20);
  1659.  
  1660. struct lua_query_extra *e = command->arg;
  1661. lua_rawgeti (luaState, LUA_REGISTRYINDEX, e->func);
  1662. lua_rawgeti (luaState, LUA_REGISTRYINDEX, e->param);
  1663.  
  1664. int i;
  1665. for (i = 0; i < arg_num; i ++) {
  1666. int j = i;
  1667. if (j > 9) { j = 9; }
  1668. while (j >= 0) {
  1669. if (command->args[j] == ca_period) { j --; continue; }
  1670. if (command->args[j] == ca_none) { j --; continue; }
  1671. break;
  1672. }
  1673. assert (j >= 0);
  1674.  
  1675. switch (command->args[j] & 0xff) {
  1676. case ca_none:
  1677. case ca_period:
  1678. assert (0);
  1679. break;
  1680. case ca_user:
  1681. case ca_chat:
  1682. case ca_secret_chat:
  1683. case ca_peer:
  1684. if (args[i].P) {
  1685. push_peer (args[i].P->id, args[i].P);
  1686. } else {
  1687. lua_pushnil (luaState);
  1688. }
  1689. break;
  1690. case ca_file_name:
  1691. case ca_file_name_end:
  1692. case ca_string_end:
  1693. case ca_string:
  1694. if (args[i].str) {
  1695. lua_pushstring (luaState, args[i].str);
  1696. } else {
  1697. lua_pushnil (luaState);
  1698. }
  1699. break;
  1700. case ca_number:
  1701. if (args[i].num != NOT_FOUND) {
  1702. lua_pushnumber (luaState, args[i].num);
  1703. } else {
  1704. lua_pushnil (luaState);
  1705. }
  1706. break;
  1707. case ca_double:
  1708. if (args[i].dval != NOT_FOUND) {
  1709. lua_pushnumber (luaState, args[i].dval);
  1710. } else {
  1711. lua_pushnil (luaState);
  1712. }
  1713. break;
  1714. }
  1715. }
  1716.  
  1717.  
  1718.  
  1719. int r = ps_lua_pcall (luaState, 1 + arg_num, 0, 0);
  1720.  
  1721. if (r) {
  1722. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  1723. }
  1724. }
  1725.  
  1726. void register_new_command (struct command *cmd);
  1727. static int register_interface_from_lua (lua_State *L) {
  1728. int n = lua_gettop (L);
  1729. if (n <= 4 || n >= 13) {
  1730. lua_pushboolean (L, 0);
  1731. return 1;
  1732. }
  1733.  
  1734. static struct command cmd;
  1735. memset (&cmd, 0, sizeof (struct command));
  1736.  
  1737. int i;
  1738. for (i = 0; i < n - 4; i++) {
  1739. const char *s = lua_tostring (L, -1);
  1740. lua_pop (L, 1);
  1741.  
  1742. if (!s || !strlen (s)) {
  1743. lua_pushboolean (L, 0);
  1744. return 1;
  1745. }
  1746.  
  1747. int len = strlen (s);
  1748. int optional = 0;
  1749. if (len > 9 && !strcmp (s + len - 9, " optional")) {
  1750. optional = ca_optional;
  1751. len -= 9;
  1752. }
  1753.  
  1754. int ok = 0;
  1755. #define VARIANT(name) \
  1756. if (len == strlen (#name) && !strncmp (s, #name, len)) {\
  1757. cmd.args[n - 5 - i] = ca_ ## name | optional; \
  1758. ok = 1; \
  1759. }
  1760.  
  1761. VARIANT (user)
  1762. VARIANT (chat)
  1763. VARIANT (secret_chat)
  1764. VARIANT (peer)
  1765. VARIANT (file_name)
  1766. VARIANT (file_name_end)
  1767. VARIANT (period)
  1768. VARIANT (number)
  1769. VARIANT (double)
  1770. VARIANT (string_end)
  1771. VARIANT (string)
  1772.  
  1773. #undef VARTIANT
  1774.  
  1775. if (!ok) {
  1776. lua_pushboolean (L, 0);
  1777. return 1;
  1778. }
  1779. }
  1780.  
  1781. const char *s = lua_tostring (L, -1);
  1782. lua_pop (L, 1);
  1783.  
  1784. cmd.desc = s ? tstrdup (s) : tstrdup ("no help provided");
  1785.  
  1786. int a1 = luaL_ref (L, LUA_REGISTRYINDEX);
  1787. int a2 = luaL_ref (L, LUA_REGISTRYINDEX);
  1788.  
  1789. struct lua_query_extra *e = malloc (sizeof (*e));
  1790. assert (e);
  1791. e->func = a2;
  1792. e->param = a1;
  1793.  
  1794. cmd.arg = e;
  1795.  
  1796. cmd.fun = do_interface_from_lua;
  1797.  
  1798. s = lua_tostring (L, -1);
  1799. lua_pop (L, 1);
  1800.  
  1801. cmd.name = tstrdup (s ? s : "none");
  1802.  
  1803. register_new_command (&cmd);
  1804.  
  1805. lua_pushboolean (L, 1);
  1806. return 1;
  1807. }
  1808.  
  1809.  
  1810. void lua_init (const char *file) {
  1811. if (!file) { return; }
  1812. have_file = 1;
  1813. luaState = luaL_newstate ();
  1814. luaL_openlibs (luaState);
  1815.  
  1816. int i = 0;
  1817. while (functions[i].name) {
  1818. my_lua_register (luaState, functions[i].name, universal_from_lua);
  1819. i ++;
  1820. }
  1821.  
  1822. lua_register (luaState, "postpone", postpone_from_lua);
  1823. lua_register (luaState, "safe_quit", safe_quit_from_lua);
  1824. lua_register (luaState, "register_interface_function", register_interface_from_lua);
  1825.  
  1826. print_start ();
  1827. int r = luaL_dofile (luaState, file);
  1828. print_end ();
  1829.  
  1830. if (r) {
  1831. logprintf ("lua: %s\n", lua_tostring (luaState, -1));
  1832. exit (1);
  1833. }
  1834. }
  1835.  
  1836. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement