// Path: BiliLiveLib/src/main/java/charlie/bililivelib/Globals.java
// 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())
//                     .build();
//         } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
//             throw new AssertionError("failed initializing bilibili ssl context!");
//         }
//     }
// 
//     public Gson gson() {
//         return gson.get();
//     }
// 
//     public HttpClientConnectionManager getConnectionPool() {
//         if (connectionPool == null) {
//             reInitializeConnectionPool();
//         }
//         return connectionPool;
//     }
// 
//     public void reInitializeConnectionPool() {
//         connectionPool = new PoolingHttpClientConnectionManager(CONNECTION_ALIVE_TIME_SECOND, TimeUnit.SECONDS);
//     }
// 
//     public void setConnectionAliveTimeSecond(int connectionAliveTimeSecond) {
//         CONNECTION_ALIVE_TIME_SECOND = connectionAliveTimeSecond;
//         reInitializeConnectionPool();
//     }
// 
// 
// }
// 
// Path: BiliLiveLib/src/main/java/charlie/bililivelib/danmaku/datamodel/GlobalAnnounceInfo.java
// @Data
// public class GlobalAnnounceInfo {
//     @SerializedName("msg")
//     private String message;
//     private int rep;
//     @SerializedName("url")
//     private String URL;
// }
// 
// Path: BiliLiveLib/src/main/java/charlie/bililivelib/danmaku/event/DanmakuEvent.java
// @Getter
// public class DanmakuEvent extends EventObject {
//     private Kind kind;
//     private Object param;
// 
//     /**
//      * Constructs a prototypical Event.
//      *
//      * @param source The object on which the Event initially occurred.
//      * @throws IllegalArgumentException if source is null.
//      */
//     public DanmakuEvent(Object source) {
//         super(source);
//     }
// 
//     public DanmakuEvent(Object source, Object param, Kind kind) {
//         super(source);
//         this.kind = kind;
//         this.param = param;
//     }
// 
//     public enum Kind {
//         JOINED, ERROR, ERROR_DOWN, NEW_DANMAKU, WATCHER_COUNT,
//         START_STOP, WELCOME_VIP, GIVE_GIFT, GLOBAL_GIFT, GLOBAL_ANNOUNCE
//     }
// }
// 
// Path: BiliLiveLib/src/main/java/charlie/bililivelib/danmaku/event/DanmakuListener.java
// public interface DanmakuListener {
//     void danmakuEvent(@NotNull DanmakuEvent event);
// 
//     void watcherCountEvent(@NotNull DanmakuEvent event);
// 
//     void errorEvent(@NotNull DanmakuEvent event);
// 
//     void startStopEvent(@NotNull DanmakuEvent event);
// 
//     void statusEvent(@NotNull DanmakuEvent event);
// 
//     void welcomeVipEvent(@NotNull DanmakuEvent event);
// 
//     void giveGiftEvent(@NotNull DanmakuEvent event);
// 
//     void globalGiftEvent(@NotNull DanmakuEvent event);
// 
//     void globalAnnounceEvent(@NotNull DanmakuEvent event);
// }


import charlie.bililivelib.Globals;
import charlie.bililivelib.danmaku.datamodel.GlobalAnnounceInfo;
import charlie.bililivelib.danmaku.event.DanmakuEvent;
import charlie.bililivelib.danmaku.event.DanmakuListener;
import com.google.gson.JsonObject;
import org.jetbrains.annotations.NotNull;
import java.util.List;
package charlie.bililivelib.danmaku.dispatch;



/**
 * 分发公告的分发器。对COMMAND为'SYS_MSG'的事件有效。
 *
 * @author Charlie Jiang
 * @since rv1
 */
public class GlobalAnnounceDispatcher extends AbstractJSONDispatcher {
    public static final String[] ACCEPTABLE_COMMANDS = {
            "SYS_MSG"
    };
    private static GlobalAnnounceDispatcher GLOBAL_INSTANCE;

    @NotNull
    public static GlobalAnnounceDispatcher getGlobalInstance() {
        if (GLOBAL_INSTANCE == null) {
            GLOBAL_INSTANCE = new GlobalAnnounceDispatcher();
        }
        return GLOBAL_INSTANCE;
    }

    @Override
// Path: BiliLiveLib/src/main/java/charlie/bililivelib/Globals.java
// 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())
//                     .build();
//         } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
//             throw new AssertionError("failed initializing bilibili ssl context!");
//         }
//     }
// 
//     public Gson gson() {
//         return gson.get();
//     }
// 
//     public HttpClientConnectionManager getConnectionPool() {
//         if (connectionPool == null) {
//             reInitializeConnectionPool();
//         }
//         return connectionPool;
//     }
// 
//     public void reInitializeConnectionPool() {
//         connectionPool = new PoolingHttpClientConnectionManager(CONNECTION_ALIVE_TIME_SECOND, TimeUnit.SECONDS);
//     }
// 
//     public void setConnectionAliveTimeSecond(int connectionAliveTimeSecond) {
//         CONNECTION_ALIVE_TIME_SECOND = connectionAliveTimeSecond;
//         reInitializeConnectionPool();
//     }
// 
// 
// }
// 
// Path: BiliLiveLib/src/main/java/charlie/bililivelib/danmaku/datamodel/GlobalAnnounceInfo.java
// @Data
// public class GlobalAnnounceInfo {
//     @SerializedName("msg")
//     private String message;
//     private int rep;
//     @SerializedName("url")
//     private String URL;
// }
// 
// Path: BiliLiveLib/src/main/java/charlie/bililivelib/danmaku/event/DanmakuEvent.java
// @Getter
// public class DanmakuEvent extends EventObject {
//     private Kind kind;
//     private Object param;
// 
//     /**
//      * Constructs a prototypical Event.
//      *
//      * @param source The object on which the Event initially occurred.
//      * @throws IllegalArgumentException if source is null.
//      */
//     public DanmakuEvent(Object source) {
//         super(source);
//     }
// 
//     public DanmakuEvent(Object source, Object param, Kind kind) {
//         super(source);
//         this.kind = kind;
//         this.param = param;
//     }
// 
//     public enum Kind {
//         JOINED, ERROR, ERROR_DOWN, NEW_DANMAKU, WATCHER_COUNT,
//         START_STOP, WELCOME_VIP, GIVE_GIFT, GLOBAL_GIFT, GLOBAL_ANNOUNCE
//     }
// }
// 
// Path: BiliLiveLib/src/main/java/charlie/bililivelib/danmaku/event/DanmakuListener.java
// public interface DanmakuListener {
//     void danmakuEvent(@NotNull DanmakuEvent event);
// 
//     void watcherCountEvent(@NotNull DanmakuEvent event);
// 
//     void errorEvent(@NotNull DanmakuEvent event);
// 
//     void startStopEvent(@NotNull DanmakuEvent event);
// 
//     void statusEvent(@NotNull DanmakuEvent event);
// 
//     void welcomeVipEvent(@NotNull DanmakuEvent event);
// 
//     void giveGiftEvent(@NotNull DanmakuEvent event);
// 
//     void globalGiftEvent(@NotNull DanmakuEvent event);
// 
//     void globalAnnounceEvent(@NotNull DanmakuEvent event);
// }


// Path: BiliLiveLib/src/main/java/charlie/bililivelib/danmaku/dispatch/GlobalAnnounceDispatcher.java
import charlie.bililivelib.Globals;
import charlie.bililivelib.danmaku.datamodel.GlobalAnnounceInfo;
import charlie.bililivelib.danmaku.event.DanmakuEvent;
import charlie.bililivelib.danmaku.event.DanmakuListener;
import com.google.gson.JsonObject;
import org.jetbrains.annotations.NotNull;
import java.util.List;

package charlie.bililivelib.danmaku.dispatch;



/**
 * 分发公告的分发器。对COMMAND为'SYS_MSG'的事件有效。
 *
 * @author Charlie Jiang
 * @since rv1
 */
public class GlobalAnnounceDispatcher extends AbstractJSONDispatcher {
    public static final String[] ACCEPTABLE_COMMANDS = {
            "SYS_MSG"
    };
    private static GlobalAnnounceDispatcher GLOBAL_INSTANCE;

    @NotNull
    public static GlobalAnnounceDispatcher getGlobalInstance() {
        if (GLOBAL_INSTANCE == null) {
            GLOBAL_INSTANCE = new GlobalAnnounceDispatcher();
        }
        return GLOBAL_INSTANCE;
    }

    @Override
    protected String[] getAcceptableCommands() {