diff --git a/common/src/main/java/ctbrec/sites/chaturbate/ChaturbateModel.java b/common/src/main/java/ctbrec/sites/chaturbate/ChaturbateModel.java index e01d3920..3a50e3d2 100644 --- a/common/src/main/java/ctbrec/sites/chaturbate/ChaturbateModel.java +++ b/common/src/main/java/ctbrec/sites/chaturbate/ChaturbateModel.java @@ -55,9 +55,15 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR public boolean isOnline(boolean ignoreCache) throws IOException, ExecutionException, InterruptedException { String roomStatus; if (ignoreCache) { - StreamInfo info = loadStreamInfo(); - roomStatus = Optional.ofNullable(info).map(i -> i.room_status).orElse(""); - LOG.trace("Model {} room status: {}", getName(), Optional.ofNullable(info).map(i -> i.room_status).orElse("unknown")); + if (isOffline()) { + roomStatus = "offline"; + onlineState = State.OFFLINE; + LOG.trace("Model {} offline", getName()); + } else { + StreamInfo info = getStreamInfo(); + roomStatus = Optional.ofNullable(info).map(i -> i.room_status).orElse(""); + LOG.trace("Model {} room status: {}", getName(), Optional.ofNullable(info).map(i -> i.room_status).orElse("unknown")); + } } else { StreamInfo info = getStreamInfo(true); roomStatus = Optional.ofNullable(info).map(i -> i.room_status).orElse(""); @@ -65,6 +71,24 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR return Objects.equals(PUBLIC, roomStatus); } + private boolean isOffline() { + String normalizedName = getName().toLowerCase().trim(); + String previewUrl = "https://roomimg.stream.highwebmedia.com/ri/" + normalizedName + ".jpg?" + Instant.now().getEpochSecond(); + Request req = new Request.Builder() + .url(previewUrl) + .header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent) + .head() + .build(); + try (Response response = getSite().getHttpClient().execute(req)) { + if (response.isSuccessful()) { + return response.header("Content-Length", "0").equals("21971"); + } + } catch (Exception ex) { + // fail silently + } + return false; + } + @Override public int[] getStreamResolution(boolean failFast) throws ExecutionException { if (failFast) { @@ -97,8 +121,12 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR if (failFast) { setOnlineStateByRoomStatus(Optional.ofNullable(streamInfo).map(si -> si.room_status).orElse("Unknown")); } else { - streamInfo = loadStreamInfo(); - setOnlineStateByRoomStatus(streamInfo.room_status); + if (isOffline()) { + onlineState = OFFLINE; + } else { + streamInfo = loadStreamInfo(); + setOnlineStateByRoomStatus(streamInfo.room_status); + } } return onlineState; } @@ -233,7 +261,7 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR } private StreamInfo loadStreamInfo() throws IOException { - if (Duration.between(lastStreamInfoRequest, Instant.now()).getSeconds() < 2) { + if (streamInfo != null && Duration.between(lastStreamInfoRequest, Instant.now()).getSeconds() < 5) { return streamInfo; } RequestBody body = new FormBody.Builder() @@ -250,7 +278,7 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR lastStreamInfoRequest = Instant.now(); if (response.isSuccessful()) { String content = response.body().string(); - LOG.trace("Raw stream info: {}", content); + LOG.trace("Raw stream info for model {}: {}", getName(), content); Moshi moshi = new Moshi.Builder().build(); JsonAdapter adapter = moshi.adapter(StreamInfo.class); streamInfo = adapter.fromJson(content);