Search in sources :

Example 1 with Item

use of com.hsn.epic4j.core.bean.Item in project epic4j by huisunan.

the class MainStart method getFreeItems.

/**
 * 获取免费游戏
 */
@Override
@Retry(message = "获取周末游戏失败", value = 10)
public List<Item> getFreeItems() {
    // https://store-site-backend-static.ak.epicgames.com/freeGamesPromotions?locale=zh-CN-CN&country=CN&allowCountries=CN
    String userCountry = "CN";
    String locate = "zh-CN";
    String formatUrl = StrUtil.format(UrlConstants.freeGameUrl, locate, userCountry, userCountry);
    log.debug(formatUrl);
    String res = HttpUtil.get(formatUrl);
    log.trace("免费游戏json串:\n{}", res);
    JSONObject json = JSONUtil.parseObj(res);
    List<Item> list = new ArrayList<>();
    DateTime now = DateUtil.date();
    for (JSONObject element : json.getByPath("data.Catalog.searchStore.elements", JSONArray.class).jsonIter()) {
        if (!"ACTIVE".equals(element.getStr("status"))) {
            continue;
        }
        if (StreamSupport.stream(element.getJSONArray("categories").jsonIter().spliterator(), false).anyMatch(item -> "freegames".equals(item.getStr("path")))) {
            JSONObject promotions = element.getJSONObject("promotions");
            if (promotions == null) {
                continue;
            }
            JSONArray promotionalOffers = promotions.getJSONArray("promotionalOffers");
            if (CollUtil.isNotEmpty(promotionalOffers)) {
                if (StreamSupport.stream(promotionalOffers.jsonIter().spliterator(), false).flatMap(offerItem -> StreamSupport.stream(offerItem.getJSONArray("promotionalOffers").jsonIter().spliterator(), false)).anyMatch(offerItem -> {
                    DateTime startDate = DateUtil.parse(offerItem.getStr("startDate")).setTimeZone(TimeZone.getDefault());
                    DateTime endDate = DateUtil.parse(offerItem.getStr("endDate")).setTimeZone(TimeZone.getDefault());
                    JSONObject discountSetting = offerItem.getJSONObject("discountSetting");
                    return DateUtil.isIn(now, startDate, endDate) && "PERCENTAGE".equals(discountSetting.getStr("discountType")) && discountSetting.getInt("discountPercentage") == 0;
                })) {
                    list.add(element.toBean(Item.class));
                }
            }
        }
    }
    return list;
}
Also used : DateUtil(cn.hutool.core.date.DateUtil) java.util(java.util) PageNavigateOptions(com.ruiyun.jvppeteer.options.PageNavigateOptions) SneakyThrows(lombok.SneakyThrows) Constant(com.ruiyun.jvppeteer.core.Constant) FileUtil(com.ruiyun.jvppeteer.util.FileUtil) RequiredArgsConstructor(lombok.RequiredArgsConstructor) Viewport(com.ruiyun.jvppeteer.options.Viewport) JSONUtil(cn.hutool.json.JSONUtil) Item(com.hsn.epic4j.core.bean.Item) HttpUtil(cn.hutool.http.HttpUtil) DateTime(cn.hutool.core.date.DateTime) StreamSupport(java.util.stream.StreamSupport) PageSlug(com.hsn.epic4j.core.bean.PageSlug) EpicConfig(com.hsn.epic4j.core.config.EpicConfig) PageUtil(com.hsn.epic4j.core.util.PageUtil) TimeException(com.hsn.epic4j.core.exception.TimeException) Browser(com.ruiyun.jvppeteer.core.browser.Browser) Puppeteer(com.ruiyun.jvppeteer.core.Puppeteer) SelectItem(com.hsn.epic4j.core.bean.SelectItem) JSONObject(cn.hutool.json.JSONObject) LaunchOptions(com.ruiyun.jvppeteer.options.LaunchOptions) LaunchOptionsBuilder(com.ruiyun.jvppeteer.options.LaunchOptionsBuilder) Collectors(java.util.stream.Collectors) ItemException(com.hsn.epic4j.core.exception.ItemException) Page(com.ruiyun.jvppeteer.core.page.Page) CollUtil(cn.hutool.core.collection.CollUtil) StrUtil(cn.hutool.core.util.StrUtil) Slf4j(lombok.extern.slf4j.Slf4j) BrowserFetcher(com.ruiyun.jvppeteer.core.browser.BrowserFetcher) JSONArray(cn.hutool.json.JSONArray) PermissionException(com.hsn.epic4j.core.exception.PermissionException) Item(com.hsn.epic4j.core.bean.Item) SelectItem(com.hsn.epic4j.core.bean.SelectItem) JSONObject(cn.hutool.json.JSONObject) JSONArray(cn.hutool.json.JSONArray) DateTime(cn.hutool.core.date.DateTime)

Example 2 with Item

use of com.hsn.epic4j.core.bean.Item in project epic4j by huisunan.

the class MainStart method receive.

@Override
@SneakyThrows
@Retry(message = "领取失败")
public List<Item> receive(Page page, List<Item> weekFreeItems) {
    if (log.isDebugEnabled()) {
        log.debug("所有免费的游戏:{}", weekFreeItems.stream().map(Item::getTitle).collect(Collectors.joining(",")));
    }
    List<Item> receiveItem = new ArrayList<>();
    for (Item item : weekFreeItems) {
        String url = getItemUrl(item);
        String itemUrl = StrUtil.format(UrlConstants.storeUrl, url);
        log.info("游戏url:{}", itemUrl);
        page.goTo(itemUrl);
        log.info("18+检测");
        PageUtil.tryClick(page, itemUrl, 8, 1000, "div[data-component=PDPAgeGate] Button");
        PageUtil.waitForTextChange(page, "div[data-component=DesktopSticky] button[data-testid=purchase-cta-button]", LOADING_TEXT);
        if (isInLibrary(page)) {
            log.debug("游戏[{}]已经在库里", item.getTitle());
            continue;
        }
        page.waitForSelector("div[data-component=DesktopSticky] button[data-testid=purchase-cta-button]").click();
        // page.waitForSelector("div[data-component=WithClickTracking] button").click();
        // epic user licence check
        log.info("首次领取游戏检测||设备检测");
        PageUtil.tryClick(page, itemUrl, 30, 100, Arrays.asList(userLicenceCheck(), platformCheck()));
        String purchaseUrl = PageUtil.getStrProperty(page, "#webPurchaseContainer iframe", "src");
        log.debug("订单链接 :{}", purchaseUrl);
        page.goTo(purchaseUrl);
        PageUtil.tryClick(page, page.mainFrame().url(), 20, 500, "#purchase-app button[class*=confirm]:not([disabled])");
        PageUtil.tryClick(page, page.mainFrame().url(), "#purchaseAppContainer div.payment-overlay button.payment-btn--primary");
        PageUtil.findSelectors(page, 30_000, true, () -> {
            throw new TimeException("订单状态检测超时");
        }, new SelectItem("#purchase-app div[class*=alert]", () -> {
            if (item.isDLC()) {
                // DLC情况下,在没有本体的情况下也也可以领取
                return SelectItem.SelectCallBack.CONTINUE;
            } else {
                String message = PageUtil.getStrProperty(page, "#purchase-app div[class*=alert]:not([disabled])", "textContent");
                throw new PermissionException(message);
            }
        }), // talon_frame_checkout_free_prod
        new SelectItem("#talon_container_checkout_free_prod[style*=visible]", () -> {
            // 需要验证码
            throw new PermissionException("检测到需要验证码");
        }), new SelectItem("#purchase-app > div", (p, i) -> p.$(i.getSelectors()) == null, () -> {
            // 当订单完成刷新时,该元素不存在,是订单完成后刷新到新页面
            page.goTo(itemUrl);
            PageUtil.waitForTextChange(page, "div[data-component=DesktopSticky] button[data-testid=purchase-cta-button]", LOADING_TEXT);
            if (!isInLibrary(page)) {
                throw new ItemException("该游戏被误认为已经认领");
            }
            log.info("游戏领取成功:{}", item.getTitle());
            receiveItem.add(item);
            return SelectItem.SelectCallBack.END;
        }));
    }
    return receiveItem;
}
Also used : PermissionException(com.hsn.epic4j.core.exception.PermissionException) DateUtil(cn.hutool.core.date.DateUtil) java.util(java.util) PageNavigateOptions(com.ruiyun.jvppeteer.options.PageNavigateOptions) SneakyThrows(lombok.SneakyThrows) Constant(com.ruiyun.jvppeteer.core.Constant) FileUtil(com.ruiyun.jvppeteer.util.FileUtil) RequiredArgsConstructor(lombok.RequiredArgsConstructor) Viewport(com.ruiyun.jvppeteer.options.Viewport) JSONUtil(cn.hutool.json.JSONUtil) Item(com.hsn.epic4j.core.bean.Item) HttpUtil(cn.hutool.http.HttpUtil) DateTime(cn.hutool.core.date.DateTime) StreamSupport(java.util.stream.StreamSupport) PageSlug(com.hsn.epic4j.core.bean.PageSlug) EpicConfig(com.hsn.epic4j.core.config.EpicConfig) PageUtil(com.hsn.epic4j.core.util.PageUtil) TimeException(com.hsn.epic4j.core.exception.TimeException) Browser(com.ruiyun.jvppeteer.core.browser.Browser) Puppeteer(com.ruiyun.jvppeteer.core.Puppeteer) SelectItem(com.hsn.epic4j.core.bean.SelectItem) JSONObject(cn.hutool.json.JSONObject) LaunchOptions(com.ruiyun.jvppeteer.options.LaunchOptions) LaunchOptionsBuilder(com.ruiyun.jvppeteer.options.LaunchOptionsBuilder) Collectors(java.util.stream.Collectors) ItemException(com.hsn.epic4j.core.exception.ItemException) Page(com.ruiyun.jvppeteer.core.page.Page) CollUtil(cn.hutool.core.collection.CollUtil) StrUtil(cn.hutool.core.util.StrUtil) Slf4j(lombok.extern.slf4j.Slf4j) BrowserFetcher(com.ruiyun.jvppeteer.core.browser.BrowserFetcher) JSONArray(cn.hutool.json.JSONArray) PermissionException(com.hsn.epic4j.core.exception.PermissionException) Item(com.hsn.epic4j.core.bean.Item) SelectItem(com.hsn.epic4j.core.bean.SelectItem) ItemException(com.hsn.epic4j.core.exception.ItemException) TimeException(com.hsn.epic4j.core.exception.TimeException) SelectItem(com.hsn.epic4j.core.bean.SelectItem) SneakyThrows(lombok.SneakyThrows)

Example 3 with Item

use of com.hsn.epic4j.core.bean.Item in project epic4j by huisunan.

the class EpicStarter method start.

protected void start() {
    checkForUpdate();
    // 获取周免游戏
    List<Item> weekFreeItems = iStart.getFreeItems().stream().peek(i -> {
        if (StrUtil.endWith(i.getProductSlug(), "/home")) {
            i.setProductSlug(i.getProductSlug().replace("/home", ""));
        }
    }).collect(Collectors.toList());
    // 处理 productSlug带/home的清空
    for (UserInfo info : userInfos) {
        doStart(info, weekFreeItems);
    }
}
Also used : DateUtil(cn.hutool.core.date.DateUtil) Proxy(java.lang.reflect.Proxy) ConsoleNotify(com.hsn.epic4j.core.notify.ConsoleNotify) ArrayList(java.util.ArrayList) JSONUtil(cn.hutool.json.JSONUtil) Item(com.hsn.epic4j.core.bean.Item) INotify(com.hsn.epic4j.core.notify.INotify) DateTime(cn.hutool.core.date.DateTime) FileUrlResource(org.springframework.core.io.FileUrlResource) ThreadPoolTaskScheduler(org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler) EpicConfig(com.hsn.epic4j.core.config.EpicConfig) PageUtil(com.hsn.epic4j.core.util.PageUtil) Browser(com.ruiyun.jvppeteer.core.browser.Browser) IoUtil(cn.hutool.core.io.IoUtil) ScreenShootUtil(com.hsn.epic4j.core.util.ScreenShootUtil) Collectors(java.util.stream.Collectors) File(java.io.File) CronTrigger(org.springframework.scheduling.support.CronTrigger) Page(com.ruiyun.jvppeteer.core.page.Page) TypeReference(cn.hutool.core.lang.TypeReference) StrUtil(cn.hutool.core.util.StrUtil) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) CookieParam(com.ruiyun.jvppeteer.protocol.network.CookieParam) DateField(cn.hutool.core.date.DateField) Data(lombok.Data) FileUtil(cn.hutool.core.io.FileUtil) FileReader(java.io.FileReader) UserInfo(com.hsn.epic4j.core.bean.UserInfo) Item(com.hsn.epic4j.core.bean.Item) UserInfo(com.hsn.epic4j.core.bean.UserInfo)

Example 4 with Item

use of com.hsn.epic4j.core.bean.Item in project epic4j by huisunan.

the class EpicStarter method doStart.

public void doStart(UserInfo userInfo, List<Item> weekFreeItems) {
    Browser browser = null;
    WatchDogThread watchDogThread = null;
    try {
        ThreadContext.init(epicConfig.getTimeout(), epicConfig.getInterval());
        String desensitizedEmail = email(userInfo.getEmail());
        log.info("账号[{}]开始工作", desensitizedEmail);
        // 用户文件路径
        String userDataPath = new FileUrlResource(epicConfig.getDataPath() + File.separator + userInfo.getEmail()).getFile().getAbsolutePath();
        log.debug("用户数据目录:{}", userDataPath.replace(userInfo.getEmail(), desensitizedEmail));
        // 获取浏览器对象
        browser = iStart.getBrowser(userDataPath);
        // 获取默认page
        Page page = iStart.getDefaultPage(browser);
        // 加载cookie
        if (StrUtil.isNotBlank(epicConfig.getCookiePath()) && FileUtil.exist(epicConfig.getCookiePath())) {
            log.debug("加载cookie");
            List<CookieParam> cookies = JSONUtil.toBean(IoUtil.read(new FileReader(epicConfig.getCookiePath())), new TypeReference<List<CookieParam>>() {
            }, false);
            page.setCookie(cookies);
        }
        // 反爬虫设置
        PageUtil.crawSet(page);
        watchDogThread = new WatchDogThread(browser, Thread.currentThread(), epicConfig.getHeadLess());
        watchDogThread.start();
        // 打开epic主页
        iStart.goToEpic(page);
        List<Page> pages = browser.pages();
        for (Page p : pages) {
            if (!StrUtil.startWith(p.mainFrame().url(), "http")) {
                p.close();
            }
        }
        boolean needLogin = iStart.needLogin(page);
        log.debug("是否需要登录:{}", needLogin ? "是" : "否");
        if (needLogin) {
            iLogin.login(page, userInfo.getEmail(), userInfo.getPassword());
        }
        // 领取游戏
        List<Item> receive = iStart.receive(page, weekFreeItems);
        for (INotify notify : notifies) {
            if (notify.notifyReceive(receive)) {
                break;
            }
        }
    } catch (Exception e) {
        if (epicConfig.getErrorScreenShoot()) {
            // 输出截图和html信息
            long currentTimeMillis = System.currentTimeMillis();
            ScreenShootUtil.screen(browser, "data/error", currentTimeMillis + ".jpeg", currentTimeMillis + ".html");
        }
        log.error("程序异常", e);
    } finally {
        if (watchDogThread != null) {
            watchDogThread.interrupt();
        }
        if (browser != null) {
            browser.close();
        }
        ThreadContext.clear();
    }
}
Also used : INotify(com.hsn.epic4j.core.notify.INotify) Page(com.ruiyun.jvppeteer.core.page.Page) CookieParam(com.ruiyun.jvppeteer.protocol.network.CookieParam) Item(com.hsn.epic4j.core.bean.Item) FileReader(java.io.FileReader) ArrayList(java.util.ArrayList) List(java.util.List) FileUrlResource(org.springframework.core.io.FileUrlResource) Browser(com.ruiyun.jvppeteer.core.browser.Browser)

Aggregations

Item (com.hsn.epic4j.core.bean.Item)4 Browser (com.ruiyun.jvppeteer.core.browser.Browser)4 Page (com.ruiyun.jvppeteer.core.page.Page)4 DateTime (cn.hutool.core.date.DateTime)3 DateUtil (cn.hutool.core.date.DateUtil)3 StrUtil (cn.hutool.core.util.StrUtil)3 JSONUtil (cn.hutool.json.JSONUtil)3 EpicConfig (com.hsn.epic4j.core.config.EpicConfig)3 PageUtil (com.hsn.epic4j.core.util.PageUtil)3 Collectors (java.util.stream.Collectors)3 Slf4j (lombok.extern.slf4j.Slf4j)3 CollUtil (cn.hutool.core.collection.CollUtil)2 HttpUtil (cn.hutool.http.HttpUtil)2 JSONArray (cn.hutool.json.JSONArray)2 JSONObject (cn.hutool.json.JSONObject)2 PageSlug (com.hsn.epic4j.core.bean.PageSlug)2 SelectItem (com.hsn.epic4j.core.bean.SelectItem)2 ItemException (com.hsn.epic4j.core.exception.ItemException)2 PermissionException (com.hsn.epic4j.core.exception.PermissionException)2 TimeException (com.hsn.epic4j.core.exception.TimeException)2