Skip to content

Commit

Permalink
Add raffle parsing to kol.js
Browse files Browse the repository at this point in the history
  • Loading branch information
gausie committed Aug 15, 2024
1 parent 9b0b6fd commit 16e38b7
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/kol.js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"tough-cookie": "^4.1.4",
"ts-dedent": "^2.2.0",
"typed-emitter": "^2.1.0",
"typescript-memoize": "^1.1.1",
"xpath": "^0.0.34"
}
}
41 changes: 41 additions & 0 deletions packages/kol.js/src/Client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,44 @@ describe("Familiars", () => {
expect(familiars).toHaveLength(206);
});
});

describe("Raffle", () => {
it("can fetch the current raffle", async () => {
text.mockResolvedValueOnce(await loadFixture(__dirname, "raffle.html"));
text.mockResolvedValueOnce("<!-- itemid: 1 -->");
text.mockResolvedValueOnce("<!-- itemid: 2 -->");
text.mockResolvedValueOnce("<!-- itemid: 3 -->");
text.mockResolvedValueOnce("<!-- itemid: 4 -->");

const raffle = await client.getRaffle();

expect(raffle).toMatchObject({
today: {
first: 1,
second: 2,
},
yesterday: [
{
player: { id: 809337, name: "Collective Consciousness" },
item: 3,
tickets: 3333,
},
{
player: { id: 852958, name: "Ryo_Sangnoir" },
item: 4,
tickets: 1011,
},
{
player: { id: 1765063, name: "SSpectre_Karasu" },
item: 4,
tickets: 1000,
},
{
player: { id: 1652370, name: "yueli7" },
item: 4,
tickets: 2040,
},
],
});
});
});
40 changes: 40 additions & 0 deletions packages/kol.js/src/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import { PlayerCache } from "./Cache.js";
import { CookieJar } from "tough-cookie";
import got, { OptionsOfJSONResponseBody, OptionsOfTextResponseBody } from "got";
import { Memoize } from "typescript-memoize";

type TypedEmitter<T extends EventMap> = TypedEventEmitter.default<T>;

Expand Down Expand Up @@ -510,4 +511,43 @@ export class Client extends (EventEmitter as unknown as new () => TypedEmitter<E

return familiars;
}

@Memoize()
async descIdToId(descId: number): Promise<number> {
const page = await this.fetchText("desc_item.php", {
searchParams: {
whichitem: descId,
},
});
return Number(page.match(/<!-- itemid: (\d+) -->/)?.[1] ?? -1);
}

async getRaffle() {
const page = await this.fetchText("raffle.php");
const today = page.matchAll(
/<tr><td align=right>(?:First|Second) Prize:<\/td>.*?descitem\((\d+)\)/g,
);
const [first, second] = await Promise.all(
today
? [...today].map(async (p) => await this.descIdToId(Number(p[1])))
: [null, null],
);
const winners = page.matchAll(
/<tr><td class=small><a href='showplayer\.php\?who=\d+'>(.*?) \(#(\d+)\).*?descitem\((\d+)\).*?([\d,]+)<\/td><\/tr>/g,
);
const yesterday = await Promise.all(
winners
? [...winners].map(async (w) => ({
player: new Player(this, Number(w[2]), w[1]),
item: await this.descIdToId(Number(w[3])),
tickets: Number(w[4].replace(",", "")),
}))
: [],
);

return {
today: { first, second },
yesterday,
};
}
}
2 changes: 0 additions & 2 deletions packages/kol.js/src/Player.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ describe("Player searching", () => {

expectNotNull(player);

console.log(player);

expect(player.id).toBe(1046951);
// Learns correct capitalisation
expect(player.name).toBe("Beldur");
Expand Down
41 changes: 41 additions & 0 deletions packages/kol.js/src/__fixtures__/raffle.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<html><head>
<script language=Javascript>
<!--
if (parent.frames.length == 0) location.href="game.php";
var actions = { "sendmessage.php" : { "action" : 1, "title" : "Send Message", "arg" : "toid" } }
var notchat = true;//-->
</script>
<script language=Javascript src="https://d2uyhvukfffg5a.cloudfront.net/scripts/keybinds.min.2.js"></script>
<script language=Javascript src="https://d2uyhvukfffg5a.cloudfront.net/scripts/window.20111231.js"></script>
<script language="javascript">function chatFocus(){if(top.chatpane.document.chatform.graf) top.chatpane.document.chatform.graf.focus();}
if (typeof defaultBind != 'undefined') { defaultBind(47, 2, chatFocus); defaultBind(190, 2, chatFocus);defaultBind(191, 2, chatFocus); defaultBind(47, 8, chatFocus);defaultBind(190, 8, chatFocus); defaultBind(191, 8, chatFocus); }</script><script language=Javascript>
var confirm_ = 0;
function conf()
{
if (!confirm_)
return true;

var select = document.f.where;
var where = select.options[select.selectedIndex].value;
if (where == 1)
return true;
else
return confirm("You are currently in ronin/hardcore. Are you sure you want to buy these tickets using your on-hand Meat?");
}
</script><script language=Javascript src="https://d2uyhvukfffg5a.cloudfront.net/scripts/jquery-1.3.1.min.js"></script>
<script language=Javascript src='https://d2uyhvukfffg5a.cloudfront.net/scripts/rcm.20160406.js'></script> <link rel="stylesheet" type="text/css" href="https://d2uyhvukfffg5a.cloudfront.net/styles.20230117d.css">
<style type='text/css'>
.faded {
zoom: 1;
filter: alpha(opacity=35);
opacity: 0.35;
-khtml-opacity: 0.35;
-moz-opacity: 0.35;
}
</style>

</head>

<body>
<div id='menu' class=rcm></div><center><table width=95% cellspacing=0 cellpadding=0><tr><td style="color: white;" align=center bgcolor=blue><b>Raffle House</b></td></tr><tr><td style="padding: 5px; border: 1px solid blue;"><center><table><tr><td><table><tr><td valign=center><img src='https://d2uyhvukfffg5a.cloudfront.net/otherimages/town/shoppeng.gif'></td><td>Greetings, Adventurer, and welcome to our Raffle House, which is completely and totally legitimate and fully-licensed by the Council of Loathing.<p> Here's how it works: you buy some raffle tickets, and every day (at rollover) we'll draw one to see who wins our Fabulous Prize, which will be delivered to you in one of our special packages. Tickets are non-transferrable, but we will accept tickets from Hagnk's if you should ascend before the drawing.<p> All proceeds will be donated to an unspecified but very worthy charity of our choosing. So, how many tickets do you want?</td></tr></table><center><b>Today's Raffle Prize:</b></center><center><table><tr><td align=right>First Prize:</td><td><img class=hand onclick='descitem(352170676);' alt='maypole' style='vertical-align: middle' src='https://d2uyhvukfffg5a.cloudfront.net/itemimages/maypole.gif'> <b>miniature gravy-covered maypole</b></td></tr></table><center><table><tr><td align=right>Second Prize:</td><td><img class=hand onclick='descitem(992809861);' alt='vcase' style='vertical-align: middle' src='https://d2uyhvukfffg5a.cloudfront.net/itemimages/vcase.gif'> <b>Doll Moll violin case</b></td></tr></table><table><tr><td>1 first prize lot and 3 second prize lots are available. One prize lot per winner. All ticket sales are final. Void where prohibited by law. Part of a complete breakfast.<p></td></tr></table><p>You haven't bought any tickets for today's raffle.<p><b>Winners of Yesterday's Raffle:</b><br><div style='max-height: 300px; overflow: auto; border: 1px dashed black; margin-left: 5%; margin-right: 5%'><table><tr><td align=center><b>Name</b></td><td align=center><b>Prize</b></td><td align=center><b>Tickets<br>Purchased</b></td></tr><tr><td class=small><a href='showplayer.php?who=809337'>Collective Consciousness (#809337)</a></td><td><img class=hand onclick='descitem(828455718);' style='vertical-align: middle' src='https://d2uyhvukfffg5a.cloudfront.net/itemimages/wintercatalog.gif'> <b>Discontent&trade; Winter Garden Catalog</b></td><td class=small>&nbsp;&nbsp;3,333</td></tr><tr><td class=small><a href='showplayer.php?who=852958'>Ryo_Sangnoir (#852958)</a></td><td><img class=hand onclick='descitem(211748296);' style='vertical-align: middle' src='https://d2uyhvukfffg5a.cloudfront.net/itemimages/wine.gif'> <b>Colera Peste Nebbiolo</b></td><td class=small>&nbsp;&nbsp;1,011</td></tr><tr><td class=small><a href='showplayer.php?who=1765063'>SSpectre_Karasu (#1765063)</a></td><td><img class=hand onclick='descitem(211748296);' style='vertical-align: middle' src='https://d2uyhvukfffg5a.cloudfront.net/itemimages/wine.gif'> <b>Colera Peste Nebbiolo</b></td><td class=small>&nbsp;&nbsp;1,000</td></tr><tr><td class=small><a href='showplayer.php?who=1652370'>yueli7 (#1652370)</a></td><td><img class=hand onclick='descitem(211748296);' style='vertical-align: middle' src='https://d2uyhvukfffg5a.cloudfront.net/itemimages/wine.gif'> <b>Colera Peste Nebbiolo</b></td><td class=small>&nbsp;&nbsp;2,040</td></tr></table></div><form name=f style='display: inline' action=raffle.php method=post onsubmit='return conf();'><input type=hidden name=action value=buy><input type=hidden name=pwd value=4cf70f166096b3abab3d98431af7094a><table><tr><td colspan=3 align=center><b>Buy Raffle Tickets:</b></td></tr><tr><td align=right><img style='vertical-align: middle' class=hand src='https://d2uyhvukfffg5a.cloudfront.net/itemimages/raffle.gif' onclick='descitem(488779797)'></td><td><b>raffle ticket</b></td><td>10,000 Meat</td></tr><tr><td colspan=3><center><input type=hidden name=where value=0><input type=submit class=button value='Buy Tickets'> <input type=text class=text name=quantity value=1 size=3></center></td></tr></table></form></center><center><p><a href='bordertown.php'>Go back to Bordertown</a></center></td></tr></table></center></td></tr><tr><td height=4></td></tr></table></center></body></html>

1 change: 1 addition & 0 deletions packages/kol.js/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"target": "ESNext",
"module": "NodeNext",
"esModuleInterop": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
Expand Down
1 change: 1 addition & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7772,6 +7772,7 @@ __metadata:
ts-dedent: "npm:^2.2.0"
typed-emitter: "npm:^2.1.0"
typescript: "npm:^5.5.3"
typescript-memoize: "npm:^1.1.1"
vitest: "npm:^1.6.0"
xpath: "npm:^0.0.34"
languageName: unknown
Expand Down

0 comments on commit 16e38b7

Please sign in to comment.