// Path: BiliLiveLib/src/main/java/charlie/bililivelib/internalutil/net/BilibiliTrustStrategy.java
// public class BilibiliTrustStrategy implements TrustStrategy {
//     //UPDATE IF BILIBILI's CERT CHANGES.
//     public static final String BILIBILI_CERT_FINGERPRINT = "3F1455BB9988290A4019687C799C507A54BA143A";
// 
//     @Contract(pure = true)
//     private static String digestMD5(byte[] data) {
//         MessageDigest messageDigest;
//         String md5Str;
//         try {
//             messageDigest = MessageDigest.getInstance("SHA1");
//             messageDigest.update(data);
//             md5Str = new BigInteger(1, messageDigest.digest()).toString(16).toUpperCase();
//         } catch (NoSuchAlgorithmException e) {
//             throw new AssertionError();
//         }
//         return md5Str;
//     }
// 
//     @Override
//     public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
//         for (X509Certificate certificate : chain) {
//             if (digestMD5(certificate.getEncoded()).equals(BILIBILI_CERT_FINGERPRINT))
//                 return true;
//         }
//         return false;
//     }
// }


import charlie.bililivelib.internalutil.net.BilibiliTrustStrategy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.Getter;
import org.apache.http.HttpHost;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.TimeUnit;
package charlie.bililivelib;



/**
 * 本单例类定义了一组在整个应用程序中的全局变量，这些变量仅用于Library内部使用且随时可能修改，请勿随意访问该类中的对象。
 *
 * @author Charlie Jiang
 * @since rv1
 */
public class Globals {
    private static final String BILI_PASSPORT_HOST_ROOT = "passport.bilibili.com";
    private static final String BILI_LIVE_HOST_ROOT = "live.bilibili.com";
    @Getter
    private static int CONNECTION_ALIVE_TIME_SECOND = 10;
    private static Globals instance;
    @Getter
    private HttpHost biliLiveRoot;
    @Getter
    private HttpHost biliPassportHttpsRoot;
    private ThreadLocal<Gson> gson;

    private HttpClientConnectionManager connectionPool;
    @Getter
    private SSLContext bilibiliSSLContext;

    public static Globals get() {
        if (instance == null) {
            instance = new Globals();
            instance.init();
        }
        return instance;
    }

    private void init() {
        biliLiveRoot = new HttpHost(BILI_LIVE_HOST_ROOT);
        //Visit bilibili passport via https. 443 is the https port.
        biliPassportHttpsRoot = new HttpHost(BILI_PASSPORT_HOST_ROOT, 443, "https");
        gson = ThreadLocal.withInitial(() -> new GsonBuilder()
                .setLenient()
                .create());

        try {
            bilibiliSSLContext = SSLContextBuilder.create()
// Path: BiliLiveLib/src/main/java/charlie/bililivelib/internalutil/net/BilibiliTrustStrategy.java
// public class BilibiliTrustStrategy implements TrustStrategy {
//     //UPDATE IF BILIBILI's CERT CHANGES.
//     public static final String BILIBILI_CERT_FINGERPRINT = "3F1455BB9988290A4019687C799C507A54BA143A";
// 
//     @Contract(pure = true)
//     private static String digestMD5(byte[] data) {
//         MessageDigest messageDigest;
//         String md5Str;
//         try {
//             messageDigest = MessageDigest.getInstance("SHA1");
//             messageDigest.update(data);
//             md5Str = new BigInteger(1, messageDigest.digest()).toString(16).toUpperCase();
//         } catch (NoSuchAlgorithmException e) {
//             throw new AssertionError();
//         }
//         return md5Str;
//     }
// 
//     @Override
//     public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
//         for (X509Certificate certificate : chain) {
//             if (digestMD5(certificate.getEncoded()).equals(BILIBILI_CERT_FINGERPRINT))
//                 return true;
//         }
//         return false;
//     }
// }


// Path: BiliLiveLib/src/main/java/charlie/bililivelib/Globals.java
import charlie.bililivelib.internalutil.net.BilibiliTrustStrategy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.Getter;
import org.apache.http.HttpHost;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.TimeUnit;

package charlie.bililivelib;



/**
 * 本单例类定义了一组在整个应用程序中的全局变量，这些变量仅用于Library内部使用且随时可能修改，请勿随意访问该类中的对象。
 *
 * @author Charlie Jiang
 * @since rv1
 */
public class Globals {
    private static final String BILI_PASSPORT_HOST_ROOT = "passport.bilibili.com";
    private static final String BILI_LIVE_HOST_ROOT = "live.bilibili.com";
    @Getter
    private static int CONNECTION_ALIVE_TIME_SECOND = 10;
    private static Globals instance;
    @Getter
    private HttpHost biliLiveRoot;
    @Getter
    private HttpHost biliPassportHttpsRoot;
    private ThreadLocal<Gson> gson;

    private HttpClientConnectionManager connectionPool;
    @Getter
    private SSLContext bilibiliSSLContext;

    public static Globals get() {
        if (instance == null) {
            instance = new Globals();
            instance.init();
        }
        return instance;
    }

    private void init() {
        biliLiveRoot = new HttpHost(BILI_LIVE_HOST_ROOT);
        //Visit bilibili passport via https. 443 is the https port.
        biliPassportHttpsRoot = new HttpHost(BILI_PASSPORT_HOST_ROOT, 443, "https");
        gson = ThreadLocal.withInitial(() -> new GsonBuilder()
                .setLenient()
                .create());

        try {
            bilibiliSSLContext = SSLContextBuilder.create()
                    .loadTrustMaterial(new BilibiliTrustStrategy())