Script to reveal what items have been lost in PvP

ereinion

Member
Because some PvPers like to steal items when attacking , and I both want swagger and a small enough inventory that I don't have to spend ages searching through it for what I want, it happens fairly regularly that an item is stolen from me that I want to reacquire. I suppose I could simply check to see if it is in my inventory to save a server hit (the inventory is stored internally in mafia, right?), but partly as an intellectual exercise and partly because that was what I thought of first, I ended up writing an ash-script which looks in the archives to see what items I've lost since I last logged on. The following code-snippet is what I've come up with so far, and I am curious if this is the right approach to what I want to do:
Code:
void main() {
    string pvp_string = visit_url("peevpee.php?place=logs");
     int firstOfMine = index_of(pvp_string,  "view]</small></a><td><a href=" + "\"" +  "showplayer.php?who=" + to_string(my_id())); //"
    string pattern = "(?<=\\/Lost)[^<]+";
    string[int, int] items_lost;
    
    // If the first fight I initiated isn't in the first 100 figths, we want the bigger version of the archive
    if (firstOfMine == -1 && pvp_string.contains_text("Show More")) {
        pvp_string = visit_url("peevpee.php?place=logs&mevs=0&oldseason=0&showmore=1");
         firstOfMine = index_of(pvp_string,  "view]</small></a><td><a href=" + "\"" +  "showplayer.php?who=" + to_string(my_id())); //"
    }
    // We only want to search the string between the first [view] and the first fight I initiated. 
    if (!(firstOfMine == -1)) {
        pvp_string = substring(pvp_string, index_of(pvp_string, "[view]"), firstOfMine);
    }
    
    items_lost = group_string(pvp_string, pattern);
    
    foreach i,j in items_lost {
        if (j==0) {
            print("Index(" + i + ", " + j + "): " + items_lost[i][j]);
        }
    }
}
As you can see I am only printing the information found so far, I guess that may be as far as I take this script too :p

However there are a few things I got curious about writing the script:
  1. Is it a good idea to reduce the size of the string I want to search first, as I am doing in the first couple of if-statements?
  2. Related to the first, should I load the longer archive straight away, or should I first see if the last fight I initiated is in the shorter archive containing the 100 most recent fights? In my experience it is quite seldom the first will be necessary.
  3. What do you think of the pattern I came up with? I think it should work for all cases? :p
  4. Why am I using a multi-dimensional map to loop through the results? I am having a bit of trouble understanding the wiki-page on group_string. Sorry, I am kind of new to regexes :p

I am looking forward to be enlightened :)
 

lostcalpolydude

Developer
Staff member
Reducing the starting string seems necessary for what you want. Loading the smaller page to begin with seems like the best plan.

I would have gone with create_matcher() instead of group_string() (regular expressions has a decent example for using that, you will want while instead of if though).
Code:
Lost ([^<]*)</small>
works well as a pattern using that approach, but it looks like it will fail if there are items with italics in the name now that I think about it. I don't know that it's any better to approach it that way.
 

Crowther

Active member
I feel sorry for you "small inventory" people. I never open up my inventory in the browser. I can access items so much faster by typing than I ever could with a mouse. This also means, I can clutter up my inventory with all sorts of worthless crap for people to steal. It's amusing watching my script by a bunch of new items at 100 meat in the mall when new content finally isn't so new. Recently, it's been adding a bunch of red stuff as cannon fodder.
 

xKiv

Active member
Alternatively, put all stealable items in closet + put 100 toasts in inventory to protect closet from stealing (<- simple-ish script), and let mafia handle uncloseting when I need something.
And then watch the logs as people still manage to steal some items that aren't marked non-tradeable/non-disposable/gift/quest, but mafia thinks they are.
 

ereinion

Member
Reducing the starting string seems necessary for what you want. Loading the smaller page to begin with seems like the best plan.
While I can see why it may affect the speed of the later matching, I am surprised to hear that it is necessary to trim the string to do what I want. Would you care to elaborate on why that is?
I would have gone with create_matcher() instead of group_string() (regular expressions has a decent example for using that, you will want while instead of if though).
Code:
Lost ([^<]*)</small>
works well as a pattern using that approach, but it looks like it will fail if there are items with italics in the name now that I think about it. I don't know that it's any better to approach it that way.
Why would you go with create_matcher instead of group_string. I think I tried using create_matcher earlier, but ended up switching to group_string because it seemed more intuitive. I think I may also have been a bit confused about what was represented by the matcher and what was represented by the group - and I am quite sure I didn't understand why the example went with printing capturing group 1 and 5 :) It may have helped if some sample output from running that script had been included on the wiki-page...

I tried checking your pattern on www.myregextester.com, which is the page I used to test the pattern I later translated to ash, but it doesn't find any matches, and it warns to check for delimiter collisions? "Lost ([^<]*)<\/small>" worked though ;) Anyway, here's a sample of the html from the archives page, if anyone wants to mess around with finding good expressions to use. If I ever run into someone stealing an item containing italics in its name, I'll see if I remember this thread and return with new page-code :)

- edit - What is the point of lookaround if you can just hardcode what is around the text you're looking for?
Alternatively, put all stealable items in closet + put 100 toasts in inventory to protect closet from stealing (<- simple-ish script), and let mafia handle uncloseting when I need something.
And then watch the logs as people still manage to steal some items that aren't marked non-tradeable/non-disposable/gift/quest, but mafia thinks they are.
But I like having my inventory available to me when I am in the relay browser and/or chat too :p

But thanks for both of your replies :)
 
Last edited:

xKiv

Active member
Thanks for the bug report about those items...

Thanks for reminding me to look into it.
Bug report sent to xKiv's brain.
Bug opened, and resolved closed.
Fix description: xKiv was taught the difference between item.discardable and autosell_price(item)>0.
 

Crowther

Active member
Thanks for reminding me to look into it.
Bug report sent to xKiv's brain.
Bug opened, and resolved closed.
Fix description: xKiv was taught the difference between item.discardable and autosell_price(item)>0.
Ha! Yeah, it was very confusing for everyone when the new PvP system rolled out. These item properties weren't entirely clear before and suddenly they became important.
 

ereinion

Member
So just in case anyone is interested in this, I've updated the code a bit. I've switched to use create_matcher, and I think the regex should handle most html-tags within the item-names now:
Code:
string decide_article(string to_check) {
    switch (char_at(to_lower_case(to_check),0)) {
        case ("a"):
        case ("e"):
        case ("i"):
        case ("o"):
        case ("u"):
        case ("y"):
            return "An ";
        default:
            return "A ";
    }
}

void main() {
    string pvp_string = visit_url("peevpee.php?place=logs");
    int firstOfMine = index_of(pvp_string, "view]</small></a><td><a href=" + "\"" + "showplayer.php?who=" + to_string(my_id())); //"
    string pattern = "\\/Lost (.+?)<\\/small>";
    
    // If the first fight I initiated isn't in the first 100 figths, we want the bigger version of the archive
    if (firstOfMine == -1 && pvp_string.contains_text("Show More")) {
        pvp_string = visit_url("peevpee.php?place=logs&mevs=0&oldseason=0&showmore=1");
        firstOfMine = index_of(pvp_string, "view]</small></a><td><a href=" + "\"" + "showplayer.php?who=" + to_string(my_id())); //"
    }
    // We only want to search the string between the first [view] and the first fight I initiated. 
    if (!(firstOfMine == -1)) {
        pvp_string = substring(pvp_string, index_of(pvp_string, "[view]"), firstOfMine);
    }
    
    matcher items_lost = create_matcher(pattern, pvp_string);
    
    while (find(items_lost)) {
        print(decide_article(group(items_lost, 1)) + group(items_lost, 1) + " was stolen.", "green");
    }
}

Comments?

Oh, and massive thanks to the people who helped me :)
 
Last edited:
Top