|  | @@ -3,8 +3,9 @@ import got from "got";
 | 
	
		
			
				|  |  |  import { logger } from "src/logging";
 | 
	
		
			
				|  |  |  import { Command, ICommandData, Plugin } from "src/model/plugin";
 | 
	
		
			
				|  |  |  import { tryDo } from "@shared/common/async_utils";
 | 
	
		
			
				|  |  | +import Jimp from "jimp";
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -const rcgRe = /<input id="rcg_image".+value="([^"]+)".*\/>/i;
 | 
	
		
			
				|  |  | +const rcgRe = /<div class="rcg-panels">\s*<img src="([^"]*)" .*\/>\s*<img src="([^"]*)" .*\/>\s*<img src="([^"]*)" .*\/>\s*<\/div>/gi;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  interface XkcdResponse {
 | 
	
		
			
				|  |  |      img: string;
 | 
	
	
		
			
				|  | @@ -40,14 +41,49 @@ export class Rcg {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          const regexResult = rcgRe.exec(result.result.body);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        if(!regexResult) {
 | 
	
		
			
				|  |  | +        if(!regexResult || regexResult.length == 0) {
 | 
	
		
			
				|  |  |              logger.error("Could not find RCG from body. Got response body: %s", result.result.body);
 | 
	
		
			
				|  |  |              await this.sendErrorMessage(message);
 | 
	
		
			
				|  |  |              return;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        const panelUrls = [regexResult[1], regexResult[2], regexResult[3]];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        const panels = [];
 | 
	
		
			
				|  |  | +        let totalWidth = 0;
 | 
	
		
			
				|  |  | +        let maxHeight = 0;
 | 
	
		
			
				|  |  | +        for (const panelUrl of panelUrls) {
 | 
	
		
			
				|  |  | +            const panelImgResult = await tryDo(Jimp.read(panelUrl));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if (!panelImgResult.ok) {
 | 
	
		
			
				|  |  | +                logger.error("Failed to download panel %s",  panelUrl);
 | 
	
		
			
				|  |  | +                await this.sendErrorMessage(message);
 | 
	
		
			
				|  |  | +                return;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            const img = panelImgResult.result;
 | 
	
		
			
				|  |  | +            const [w, h] = [ img.getWidth(), img.getHeight() ];
 | 
	
		
			
				|  |  | +            panels.push(img);
 | 
	
		
			
				|  |  | +            totalWidth += w;
 | 
	
		
			
				|  |  | +            
 | 
	
		
			
				|  |  | +            if (h > maxHeight) {
 | 
	
		
			
				|  |  | +                maxHeight = h;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        const PADDING = 5;
 | 
	
		
			
				|  |  | +        let newImg = await Jimp.create(PADDING * 4 + totalWidth, PADDING * 2 + maxHeight, "white");
 | 
	
		
			
				|  |  | +        let curX = PADDING;
 | 
	
		
			
				|  |  | +        for (const panel of panels) {
 | 
	
		
			
				|  |  | +            newImg = await newImg.blit(panel, curX, PADDING);
 | 
	
		
			
				|  |  | +            curX += panel.getWidth() + PADDING;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        newImg.quality(80);
 | 
	
		
			
				|  |  | +        const buffer = await newImg.getBufferAsync(Jimp.MIME_JPEG);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          const messagePostResult = await tryDo(message.reply("I find this very funny:", {
 | 
	
		
			
				|  |  | -            files: [ regexResult[1].trim() ]
 | 
	
		
			
				|  |  | +            files: [ buffer ]
 | 
	
		
			
				|  |  |          }));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          if (!messagePostResult.ok) {
 |