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;
}
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;
}
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);
}
}
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();
}
}
Aggregations