Use USERNAMELOOKUP message to get the current SessionState for a model
This commit is contained in:
parent
cea5eac9de
commit
7577379885
|
@ -1,52 +1,32 @@
|
|||
package ctbrec.sites.mfc;
|
||||
|
||||
import static ctbrec.io.HttpConstants.*;
|
||||
import static ctbrec.sites.mfc.MessageTypes.*;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.squareup.moshi.JsonAdapter;
|
||||
import com.squareup.moshi.Moshi;
|
||||
|
||||
import ctbrec.Config;
|
||||
import ctbrec.StringUtil;
|
||||
import ctbrec.io.HttpException;
|
||||
import okhttp3.Cookie;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.WebSocket;
|
||||
import okhttp3.WebSocketListener;
|
||||
import okhttp3.*;
|
||||
import okio.ByteString;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static ctbrec.io.HttpConstants.*;
|
||||
import static ctbrec.sites.mfc.MessageTypes.*;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
public class MyFreeCamsClient {
|
||||
|
||||
|
@ -213,7 +193,7 @@ public class MyFreeCamsClient {
|
|||
MyFreeCamsClient.this.ws = null;
|
||||
}
|
||||
|
||||
private StringBuilder msgBuffer = new StringBuilder();
|
||||
private final StringBuilder msgBuffer = new StringBuilder();
|
||||
|
||||
@Override
|
||||
public void onMessage(WebSocket webSocket, String text) {
|
||||
|
@ -284,7 +264,7 @@ public class MyFreeCamsClient {
|
|||
break;
|
||||
case EXTDATA:
|
||||
if (message.getArg1() == MessageTypes.LOGIN) {
|
||||
|
||||
// noop
|
||||
} else if (message.getArg1() == MessageTypes.MANAGELIST) {
|
||||
requestExtData(message.getMessage());
|
||||
} else {
|
||||
|
@ -305,7 +285,7 @@ public class MyFreeCamsClient {
|
|||
json = new JSONObject(message.getMessage());
|
||||
tkx = json.getString("tkx");
|
||||
cxid = json.getInt("cxid");
|
||||
ctxenc = URLDecoder.decode(json.getString("ctxenc"), "utf-8");
|
||||
ctxenc = URLDecoder.decode(json.getString("ctxenc"), UTF_8);
|
||||
JSONArray ctxArray = json.getJSONArray("ctx");
|
||||
ctx = new int[ctxArray.length()];
|
||||
for (int i = 0; i < ctxArray.length(); i++) {
|
||||
|
@ -317,8 +297,6 @@ public class MyFreeCamsClient {
|
|||
break;
|
||||
}
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
LOG.error("Error while decoding ctxenc URL", e);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Exception occured while processing websocket message {}", msgBuffer, e);
|
||||
ws.close(1000, "");
|
||||
|
@ -360,7 +338,7 @@ public class MyFreeCamsClient {
|
|||
LOG.trace("Requesting EXTDATA {}", url);
|
||||
try (Response resp = mfc.getHttpClient().execute(req)) {
|
||||
if (resp.isSuccessful()) {
|
||||
parseExtDataSessionStates(resp.body().string());
|
||||
parseExtDataSessionStates(Objects.requireNonNull(resp.body(), "HTTP response is null").string());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -483,7 +461,7 @@ public class MyFreeCamsClient {
|
|||
return websocket;
|
||||
}
|
||||
|
||||
private Message parseMessage(StringBuilder msgBuffer) throws UnsupportedEncodingException {
|
||||
private Message parseMessage(StringBuilder msgBuffer) {
|
||||
int packetLengthBytes = 6;
|
||||
if (msgBuffer.length() < packetLengthBytes) {
|
||||
// packet size not transmitted completely
|
||||
|
@ -503,12 +481,12 @@ public class MyFreeCamsClient {
|
|||
int receiver = parseNextInt(rawMessage);
|
||||
int arg1 = parseNextInt(rawMessage);
|
||||
int arg2 = parseNextInt(rawMessage);
|
||||
Message message = new Message(type, sender, receiver, arg1, arg2, URLDecoder.decode(rawMessage.toString(), "utf-8"));
|
||||
Message message = new Message(type, sender, receiver, arg1, arg2, URLDecoder.decode(rawMessage.toString(), UTF_8));
|
||||
msgBuffer.delete(0, packetLength);
|
||||
return message;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("StringBuilder contains invalid data {}", msgBuffer.toString(), e);
|
||||
LOG.error("StringBuilder contains invalid data {}", msgBuffer, e);
|
||||
String logfile = "mfc_messages.log";
|
||||
try (FileOutputStream fout = new FileOutputStream(logfile)) {
|
||||
for (String string : receivedTextHistory) {
|
||||
|
@ -564,7 +542,7 @@ public class MyFreeCamsClient {
|
|||
if (isBroadcasterOnOBS(state)) {
|
||||
JSONArray array = new JSONArray();
|
||||
Arrays.stream(ctx).forEach(array::put);
|
||||
userData.put("vidctx", Base64.getEncoder().encodeToString(array.toString().getBytes(StandardCharsets.UTF_8)));
|
||||
userData.put("vidctx", Base64.getEncoder().encodeToString(array.toString().getBytes(UTF_8)));
|
||||
userData.put("cxid", cxid);
|
||||
}
|
||||
userData.put("mode", "DOWNLOAD");
|
||||
|
@ -599,11 +577,10 @@ public class MyFreeCamsClient {
|
|||
MyFreeCamsClient.this.ws = null;
|
||||
}
|
||||
} else {
|
||||
// we are establishing a new connection at the moment, not need to
|
||||
// do anything
|
||||
// we are establishing a new connection at the moment, no need to do anything
|
||||
}
|
||||
|
||||
Thread.sleep(TimeUnit.SECONDS.toMillis(15));
|
||||
TimeUnit.SECONDS.sleep(15);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
LOG.warn("Websocket watchdog has been interrupted");
|
||||
|
@ -621,7 +598,7 @@ public class MyFreeCamsClient {
|
|||
for (SessionState state : sessionStates.asMap().values()) {
|
||||
Optional<String> nm = Optional.ofNullable(state.getNm());
|
||||
Optional<String> name = Optional.ofNullable(model.getName());
|
||||
if(!nm.isPresent() || !name.isPresent()) {
|
||||
if(nm.isEmpty() || name.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -675,8 +652,7 @@ public class MyFreeCamsClient {
|
|||
}
|
||||
|
||||
public SessionState getSessionState(ctbrec.Model model) {
|
||||
if (model instanceof MyFreeCamsModel) {
|
||||
MyFreeCamsModel mfcModel = (MyFreeCamsModel) model;
|
||||
if (model instanceof MyFreeCamsModel mfcModel) {
|
||||
for (SessionState state : sessionStates.asMap().values()) {
|
||||
if (mfcModel.getUid() > 0 && state.getUid() != null && state.getUid() > 0 && mfcModel.getUid() == state.getUid()) {
|
||||
return state;
|
||||
|
@ -691,39 +667,40 @@ public class MyFreeCamsClient {
|
|||
}
|
||||
|
||||
public List<ctbrec.Model> search(String q) throws InterruptedException {
|
||||
LOG.debug("Sending USERNAMELOOKUP for {}", q);
|
||||
int msgId = messageId++;
|
||||
Object monitor = new Object();
|
||||
List<ctbrec.Model> result = new ArrayList<>();
|
||||
responseHandlers.put(msgId, msg -> {
|
||||
LOG.debug("Search result: {}", msg);
|
||||
if (StringUtil.isNotBlank(msg.getMessage()) && !Objects.equals(msg.getMessage(), q)) {
|
||||
JSONObject json = new JSONObject(msg.getMessage());
|
||||
String name = json.getString("nm");
|
||||
MyFreeCamsModel model = mfc.createModel(name);
|
||||
model.setUid(json.getInt("uid"));
|
||||
model.setMfcState(State.of(json.getInt("vs")));
|
||||
String uid = Integer.toString(model.getUid());
|
||||
String uidStart = uid.substring(0, 3);
|
||||
String previewUrl = "https://img.mfcimg.com/photos2/" + uidStart + '/' + uid + "/avatar.90x90.jpg";
|
||||
model.setPreview(previewUrl);
|
||||
result.add(model);
|
||||
}
|
||||
if (ws != null) {
|
||||
LOG.trace("Sending USERNAMELOOKUP for {}", q);
|
||||
Object monitor = new Object();
|
||||
int msgId = messageId++;
|
||||
responseHandlers.put(msgId, msg -> {
|
||||
LOG.trace("Search result: {}", msg);
|
||||
if (StringUtil.isNotBlank(msg.getMessage()) && !Objects.equals(msg.getMessage(), q)) {
|
||||
JSONObject json = new JSONObject(msg.getMessage());
|
||||
String name = json.getString("nm");
|
||||
MyFreeCamsModel model = mfc.createModel(name);
|
||||
model.setUid(json.getInt("uid"));
|
||||
model.setMfcState(State.of(json.getInt("vs")));
|
||||
String uid = Integer.toString(model.getUid());
|
||||
String uidStart = uid.substring(0, 3);
|
||||
String previewUrl = "https://img.mfcimg.com/photos2/" + uidStart + '/' + uid + "/avatar.90x90.jpg";
|
||||
model.setPreview(previewUrl);
|
||||
result.add(model);
|
||||
}
|
||||
synchronized (monitor) {
|
||||
monitor.notifyAll();
|
||||
}
|
||||
});
|
||||
ws.send("10 " + sessionId + " 0 " + msgId + " 0 " + q + "\n");
|
||||
synchronized (monitor) {
|
||||
monitor.notifyAll();
|
||||
monitor.wait();
|
||||
}
|
||||
});
|
||||
ws.send("10 " + sessionId + " 0 " + msgId + " 0 " + q + "\n");
|
||||
synchronized (monitor) {
|
||||
monitor.wait();
|
||||
}
|
||||
|
||||
for (MyFreeCamsModel model : models.asMap().values()) {
|
||||
if (StringUtil.isNotBlank(model.getName()) && model.getName().toLowerCase().contains(q.toLowerCase())) {
|
||||
result.add(model);
|
||||
for (MyFreeCamsModel model : models.asMap().values()) {
|
||||
if (StringUtil.isNotBlank(model.getName()) && model.getName().toLowerCase().contains(q.toLowerCase())) {
|
||||
result.add(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,22 +59,13 @@ public class MyFreeCamsModel extends AbstractModel {
|
|||
@Override
|
||||
public boolean isOnline(boolean ignoreCache) throws IOException, ExecutionException, InterruptedException {
|
||||
if (ignoreCache) {
|
||||
String sessionId = MyFreeCamsClient.getInstance().getSessionId(getName());
|
||||
boolean online = !(sessionId.isEmpty() || sessionId.equals("0"));
|
||||
SessionState sessionState = MyFreeCamsClient.getInstance().getSessionState(this);
|
||||
if (online) {
|
||||
if (sessionState == null) {
|
||||
LOG.warn("MFC model {} [{}] seems to be online but a SessionState could not be found", getName(), getUid());
|
||||
} else {
|
||||
return state == ctbrec.sites.mfc.State.ONLINE;
|
||||
}
|
||||
} else {
|
||||
state = ctbrec.sites.mfc.State.OFFLINE;
|
||||
List<ctbrec.Model> searchResult = MyFreeCamsClient.getInstance().search(getName());
|
||||
if (!searchResult.isEmpty()) {
|
||||
MyFreeCamsModel m = (MyFreeCamsModel) searchResult.get(0);
|
||||
this.onlineState = m.getOnlineState(true);
|
||||
}
|
||||
return online;
|
||||
} else {
|
||||
return isOnline();
|
||||
}
|
||||
return isOnline();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -369,7 +360,7 @@ public class MyFreeCamsModel extends AbstractModel {
|
|||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put(ACCEPT, "*/*");
|
||||
headers.put(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage());
|
||||
headers.put(CONNECTION, KEEP_ALIVE);
|
||||
headers.put(CONNECTION, "close");
|
||||
if (getSite() != null) {
|
||||
headers.put(ORIGIN, getSite().getBaseUrl());
|
||||
headers.put(REFERER, getSite().getBaseUrl());
|
||||
|
|
Loading…
Reference in New Issue