Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // A stab at potentially automating Secret Crimbo.
- // Reads sender_tab_recipient.tsv from the Mafia data directory, which must
- // contain a tab-separated list of senders-to-recipients, so something like this:
- // hugmeir\tnot_hugmeir
- // Will then read the last 400 messages received by this account, and for any message
- // that has a sender->recipient mapping, will forward the message to the recipient.
- // The forwarding maintains the same outside message & inside message, as well as
- // items & meat sent.
- //
- // Will ONLY forward messages with items and/or meat. Text-only messages will be ignored.
- // Will not send anything unless the wet_run variable is manually set to true.
- // Will prompt the user before every message, giving a preview of what will be sent.
- // Will not re-send the same message twice; it keeps a file called crimbo_message_ids.txt
- // in the mafia data directory, which has the msg IDs that have been processed. To
- // re-forward a message, that file has to be manually modified.
- import "zlib.ash";
- // send_gift & load_kmail were stolen wholesome from zlib,
- // then slightly modified.
- boolean send_gift_using_post(string to, string message, int meat, int[item] goodies, string insidenote) {
- // parse items into query string & figure out what sort of package we need
- int pnum = 0;
- string itemstring;
- foreach i in goodies {
- pnum += 1;
- int j = pnum;
- itemstring = itemstring
- + "&howmany"+j + "=" + goodies[i]
- + "&whichitem"+j + "=" + to_int(i);
- }
- // send gift
- string url = "town_sendgift.php?pwd="
- + "&towho=" + to
- + "¬e=" + message
- + "&insidenote=" + insidenote
- + "&whichpackage=" + pnum
- + "&sendmeat=" + meat
- + "&fromwhere=0"
- + "&action=Yep."
- + itemstring;
- // visit_url(url, usePost, urlEncoded)
- string result = visit_url(url, true, true);
- if ( !contains_text(result,"Package sent.") ) {
- vprint("The message didn't send for some reason.", -2);
- return false;
- }
- return true;
- }
- // also stol^Wborrowed from zlib
- record kmessage_with_inner_message {
- int id; // message id
- string type; // possible values observed thus far: normal, giftshop
- int fromid; // sender's playerid (0 for npc's)
- int azunixtime; // KoL server's unix timestamp
- string message; // message (not including items/meat)
- int[item] items; // items included in the message
- int meat; // meat included in the message
- string fromname; // sender's playername
- string localtime; // your local time according to your KoL account, human-readable string
- string inner_message; // Inner message, if any
- };
- kmessage_with_inner_message[int] my_mail;
- string message_matcher_re = "'id' =\\> '(\\d+)',\\s+'type' =\\> '(.+?)',\\s+'fromid' =\\> '(-?\\d+)',\\s+'azunixtime' =\\> '(\\d+)',\\s+'message' =\\> '(.+?)',\\s+'fromname' =\\> '(.+?)',\\s+'localtime' =\\> '(.+?)'";
- string inner_message_re = "\\<p\\>Inside Note:\\<p\\>(([^\\<]+|\\<br\\>)+)\\<center\\>";
- void load_kmail_with_inner_messages(string calledby, int count) {
- my_mail.clear();
- string messages = visit_url(
- "api.php?pwd"
- + "&what=kmail"
- + "&format=php"
- + "&count=" + count
- + "&for=" + url_encode(calledby)
- );
- matcher k = create_matcher(message_matcher_re,messages);
- int n;
- while ( k.find() ) {
- string message_raw = k.group(5).replace_string("\\'","'");
- n = count(my_mail);
- my_mail[n].id = to_int(k.group(1));
- my_mail[n].type = k.group(2);
- my_mail[n].fromid = to_int(k.group(3));
- my_mail[n].azunixtime = to_int(k.group(4));
- my_mail[n].fromname = k.group(6);
- my_mail[n].localtime = k.group(7);
- matcher mbits = create_matcher(
- "(.*?)\\<center\\>(.+?)$",
- message_raw
- );
- if (mbits.find()) {
- my_mail[n].meat = extract_meat(mbits.group(2));
- my_mail[n].items = extract_items(mbits.group(2));
- my_mail[n].message = mbits.group(
- to_int(my_mail[n].meat > 0
- ||
- count(my_mail[n].items) > 0)
- );
- }
- else {
- my_mail[n].message = k.group(5);
- }
- // Try to find the "Inner Message" text:
- matcher inside_message = create_matcher(
- inner_message_re,
- message_raw
- );
- if ( inside_message.find() ) {
- my_mail[n].inner_message = inside_message.group(1);
- }
- }
- }
- string sender_to_recipient_file = "sender_tab_recipient.tsv";
- string handled_messages_file = "crimbo_message_ids.txt";
- string [string] sender_to_recipient;
- boolean [int] message_id_handled;
- int [string] package_item;
- void mark_as_sent(int kmail_id) {
- // Mark the message as handled
- message_id_handled[kmail_id] = true;
- // Immediately store changes.
- map_to_file(message_id_handled, handled_messages_file);
- }
- string replace_br(string original) {
- // spent two fucking hours here because I kept using \n
- // instead of \r\n and I need to get that rage out of my
- // chest. Please understand.
- return original.replace_string("<br>", "\r\n");
- }
- boolean wet_run = false;
- file_to_map(sender_to_recipient_file, sender_to_recipient);
- file_to_map(handled_messages_file, message_id_handled);
- file_to_map("packages.txt", package_item);
- load_kmail_with_inner_messages("testing_automating_secret_crimbo", 400);
- print("Start!");
- foreach idx, kmail in my_mail {
- // Have we handled this message before?
- if ( message_id_handled[kmail.id] ) {
- print("already handled " + kmail.id);
- continue;
- }
- string sender_name = kmail.fromname;
- string recipient_name = sender_to_recipient[sender_name];
- if ( recipient_name == "" ) {
- print("No clue who " + sender_name + " should be mailing");
- continue;
- }
- int recipient_id = get_player_id(recipient_name).to_int();
- int [item] goodies;
- buffer items_being_sent;
- foreach this_item, amount in kmail.items {
- if ( package_item[ this_item.to_string() ] > 0 )
- continue;
- if ( goodies.count() != 0 ) {
- items_being_sent.append(" & ");
- }
- items_being_sent.append(this_item + " (" + amount + ")");
- goodies[ this_item ] = amount;
- }
- if ( items_being_sent.to_string() == "" && kmail.meat == 0 ) {
- mark_as_sent(kmail.id);
- continue;
- }
- // Okay, couple of things here.
- // Each message may consist of multiple lines. Each line
- // is marked by a <br>. Replace those with \r\n
- // Each message may have entities encoded inside.
- // Stuff like >.> will be >.>. Decode those.
- // Finally, url_encode everything, because there may
- // be arbitrary &'s in the message text.
- string url_encoded_message = url_encode(entity_decode(replace_br(kmail.message)));
- string url_encoded_inner = url_encode(entity_decode(replace_br(kmail.inner_message)));
- print("RAW data for " + recipient_name);
- print("RAW MESSAGE: " + url_encoded_message);
- print("RAW INNER MESSAGE: " + url_encoded_inner);
- string confirm_message = "Should we send this to " + recipient_name + " (#" + recipient_id + ")?\n"
- + "MESSAGE: " + entity_decode(replace_br(kmail.message)) + "\n"
- + "INNER MESSAGE: " + entity_decode(replace_br(kmail.inner_message)) + "\n"
- + "MEAT: " + kmail.meat + "\n"
- + "ITEMS: " + items_being_sent.to_string()
- + "\n";
- boolean should_send = user_confirm(confirm_message);
- if ( !should_send ) {
- print("Manually picked not to send message to" + recipient_name);
- continue;
- }
- if ( !wet_run ) {
- print("NOT a wet run, nothing actually sent");
- continue;
- }
- send_gift_using_post(
- recipient_id, // Use the ID to avoid shenanigans with weird names.
- url_encoded_message,
- kmail.meat,
- goodies,
- url_encoded_inner
- );
- mark_as_sent(kmail.id);
- }
- print("Finished!");
Advertisement
Add Comment
Please, Sign In to add comment