hugmeir

Untitled

Dec 22nd, 2017
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.63 KB | None | 0 0
  1. // A stab at potentially automating Secret Crimbo.
  2. // Reads sender_tab_recipient.tsv from the Mafia data directory, which must
  3. // contain a tab-separated list of senders-to-recipients, so something like this:
  4. // hugmeir\tnot_hugmeir
  5. // Will then read the last 400 messages received by this account, and for any message
  6. // that has a sender->recipient mapping, will forward the message to the recipient.
  7. // The forwarding maintains the same outside message & inside message, as well as
  8. // items & meat sent.
  9. //
  10. // Will ONLY forward messages with items and/or meat. Text-only messages will be ignored.
  11. // Will not send anything unless the wet_run variable is manually set to true.
  12. // Will prompt the user before every message, giving a preview of what will be sent.
  13. // Will not re-send the same message twice; it keeps a file called crimbo_message_ids.txt
  14. // in the mafia data directory, which has the msg IDs that have been processed. To
  15. // re-forward a message, that file has to be manually modified.
  16. import "zlib.ash";
  17.  
  18. // send_gift & load_kmail were stolen wholesome from zlib,
  19. // then slightly modified.
  20.  
  21. boolean send_gift_using_post(string to, string message, int meat, int[item] goodies, string insidenote) {
  22. // parse items into query string & figure out what sort of package we need
  23. int pnum = 0;
  24. string itemstring;
  25. foreach i in goodies {
  26. pnum += 1;
  27. int j = pnum;
  28. itemstring = itemstring
  29. + "&howmany"+j + "=" + goodies[i]
  30. + "&whichitem"+j + "=" + to_int(i);
  31. }
  32.  
  33. // send gift
  34. string url = "town_sendgift.php?pwd="
  35. + "&towho=" + to
  36. + "&note=" + message
  37. + "&insidenote=" + insidenote
  38. + "&whichpackage=" + pnum
  39. + "&sendmeat=" + meat
  40. + "&fromwhere=0"
  41. + "&action=Yep."
  42. + itemstring;
  43.  
  44. // visit_url(url, usePost, urlEncoded)
  45. string result = visit_url(url, true, true);
  46. if ( !contains_text(result,"Package sent.") ) {
  47. vprint("The message didn't send for some reason.", -2);
  48. return false;
  49. }
  50.  
  51. return true;
  52. }
  53.  
  54. // also stol^Wborrowed from zlib
  55. record kmessage_with_inner_message {
  56. int id; // message id
  57. string type; // possible values observed thus far: normal, giftshop
  58. int fromid; // sender's playerid (0 for npc's)
  59. int azunixtime; // KoL server's unix timestamp
  60. string message; // message (not including items/meat)
  61. int[item] items; // items included in the message
  62. int meat; // meat included in the message
  63. string fromname; // sender's playername
  64. string localtime; // your local time according to your KoL account, human-readable string
  65. string inner_message; // Inner message, if any
  66. };
  67. kmessage_with_inner_message[int] my_mail;
  68. string message_matcher_re = "'id' =\\> '(\\d+)',\\s+'type' =\\> '(.+?)',\\s+'fromid' =\\> '(-?\\d+)',\\s+'azunixtime' =\\> '(\\d+)',\\s+'message' =\\> '(.+?)',\\s+'fromname' =\\> '(.+?)',\\s+'localtime' =\\> '(.+?)'";
  69. string inner_message_re = "\\<p\\>Inside Note:\\<p\\>(([^\\<]+|\\<br\\>)+)\\<center\\>";
  70. void load_kmail_with_inner_messages(string calledby, int count) {
  71. my_mail.clear();
  72. string messages = visit_url(
  73. "api.php?pwd"
  74. + "&what=kmail"
  75. + "&format=php"
  76. + "&count=" + count
  77. + "&for=" + url_encode(calledby)
  78. );
  79. matcher k = create_matcher(message_matcher_re,messages);
  80. int n;
  81. while ( k.find() ) {
  82. string message_raw = k.group(5).replace_string("\\'","'");
  83.  
  84. n = count(my_mail);
  85. my_mail[n].id = to_int(k.group(1));
  86. my_mail[n].type = k.group(2);
  87. my_mail[n].fromid = to_int(k.group(3));
  88. my_mail[n].azunixtime = to_int(k.group(4));
  89. my_mail[n].fromname = k.group(6);
  90. my_mail[n].localtime = k.group(7);
  91.  
  92. matcher mbits = create_matcher(
  93. "(.*?)\\<center\\>(.+?)$",
  94. message_raw
  95. );
  96. if (mbits.find()) {
  97. my_mail[n].meat = extract_meat(mbits.group(2));
  98. my_mail[n].items = extract_items(mbits.group(2));
  99. my_mail[n].message = mbits.group(
  100. to_int(my_mail[n].meat > 0
  101. ||
  102. count(my_mail[n].items) > 0)
  103. );
  104. }
  105. else {
  106. my_mail[n].message = k.group(5);
  107. }
  108.  
  109. // Try to find the "Inner Message" text:
  110. matcher inside_message = create_matcher(
  111. inner_message_re,
  112. message_raw
  113. );
  114. if ( inside_message.find() ) {
  115. my_mail[n].inner_message = inside_message.group(1);
  116. }
  117. }
  118. }
  119.  
  120. string sender_to_recipient_file = "sender_tab_recipient.tsv";
  121. string handled_messages_file = "crimbo_message_ids.txt";
  122.  
  123. string [string] sender_to_recipient;
  124. boolean [int] message_id_handled;
  125. int [string] package_item;
  126. void mark_as_sent(int kmail_id) {
  127. // Mark the message as handled
  128. message_id_handled[kmail_id] = true;
  129. // Immediately store changes.
  130. map_to_file(message_id_handled, handled_messages_file);
  131. }
  132.  
  133. string replace_br(string original) {
  134. // spent two fucking hours here because I kept using \n
  135. // instead of \r\n and I need to get that rage out of my
  136. // chest. Please understand.
  137. return original.replace_string("<br>", "\r\n");
  138. }
  139.  
  140. boolean wet_run = false;
  141.  
  142. file_to_map(sender_to_recipient_file, sender_to_recipient);
  143. file_to_map(handled_messages_file, message_id_handled);
  144. file_to_map("packages.txt", package_item);
  145.  
  146. load_kmail_with_inner_messages("testing_automating_secret_crimbo", 400);
  147.  
  148. print("Start!");
  149. foreach idx, kmail in my_mail {
  150. // Have we handled this message before?
  151. if ( message_id_handled[kmail.id] ) {
  152. print("already handled " + kmail.id);
  153. continue;
  154. }
  155.  
  156. string sender_name = kmail.fromname;
  157. string recipient_name = sender_to_recipient[sender_name];
  158.  
  159. if ( recipient_name == "" ) {
  160. print("No clue who " + sender_name + " should be mailing");
  161. continue;
  162. }
  163. int recipient_id = get_player_id(recipient_name).to_int();
  164.  
  165. int [item] goodies;
  166. buffer items_being_sent;
  167. foreach this_item, amount in kmail.items {
  168. if ( package_item[ this_item.to_string() ] > 0 )
  169. continue;
  170.  
  171. if ( goodies.count() != 0 ) {
  172. items_being_sent.append(" & ");
  173. }
  174. items_being_sent.append(this_item + " (" + amount + ")");
  175.  
  176. goodies[ this_item ] = amount;
  177. }
  178.  
  179. if ( items_being_sent.to_string() == "" && kmail.meat == 0 ) {
  180. mark_as_sent(kmail.id);
  181. continue;
  182. }
  183.  
  184. // Okay, couple of things here.
  185. // Each message may consist of multiple lines. Each line
  186. // is marked by a <br>. Replace those with \r\n
  187. // Each message may have entities encoded inside.
  188. // Stuff like >.> will be &gt.&gt. Decode those.
  189. // Finally, url_encode everything, because there may
  190. // be arbitrary &'s in the message text.
  191. string url_encoded_message = url_encode(entity_decode(replace_br(kmail.message)));
  192. string url_encoded_inner = url_encode(entity_decode(replace_br(kmail.inner_message)));
  193.  
  194. print("RAW data for " + recipient_name);
  195. print("RAW MESSAGE: " + url_encoded_message);
  196. print("RAW INNER MESSAGE: " + url_encoded_inner);
  197.  
  198. string confirm_message = "Should we send this to " + recipient_name + " (#" + recipient_id + ")?\n"
  199. + "MESSAGE: " + entity_decode(replace_br(kmail.message)) + "\n"
  200. + "INNER MESSAGE: " + entity_decode(replace_br(kmail.inner_message)) + "\n"
  201. + "MEAT: " + kmail.meat + "\n"
  202. + "ITEMS: " + items_being_sent.to_string()
  203. + "\n";
  204. boolean should_send = user_confirm(confirm_message);
  205.  
  206. if ( !should_send ) {
  207. print("Manually picked not to send message to" + recipient_name);
  208. continue;
  209. }
  210.  
  211. if ( !wet_run ) {
  212. print("NOT a wet run, nothing actually sent");
  213. continue;
  214. }
  215.  
  216. send_gift_using_post(
  217. recipient_id, // Use the ID to avoid shenanigans with weird names.
  218. url_encoded_message,
  219. kmail.meat,
  220. goodies,
  221. url_encoded_inner
  222. );
  223. mark_as_sent(kmail.id);
  224. }
  225.  
  226. print("Finished!");
Advertisement
Add Comment
Please, Sign In to add comment