soop-chat-client
Version:
SOOP Live Chat Client
306 lines (299 loc) • 9.71 kB
text/typescript
import WebSocket from 'ws';
import { TypedEmitter } from 'tiny-typed-emitter';
type StreamInfoOnline = {
CHANNEL: {
geo_cc: string;
geo_rc: string;
acpt_lang: string;
svc_lang: string;
ISSP: number;
RESULT: 1;
LOWLAYTENCYBJ: number;
VIEWPRESET: [[Object], [Object], [Object], [Object], [Object]];
PBNO: string;
BNO: string;
BJID: string;
BJNICK: string;
BJGRADE: number;
STNO: string;
ISFAV: string;
CATE: string;
CPNO: number;
GRADE: string;
BTYPE: string;
CHATNO: string;
BPWD: 'N' | 'Y';
TITLE: string;
BPS: string;
RESOLUTION: string;
CTIP: string;
CTPT: string;
VBT: string;
CTUSER: number;
S1440P: number;
AUTO_HASHTAGS: string[];
CATEGORY_TAGS: string[];
HASH_TAGS: string[];
CHIP: string;
CHPT: string;
CHDOMAIN: string;
GWIP: string;
GWPT: string;
STYPE: string;
CDN: string;
RMD: string;
ORG: string;
MDPT: string;
BTIME: number;
DH: number;
WC: number;
PCON: number;
PCON_TIME: number;
PCON_MONTH: string[];
PCON_OBJECT: {
tier1: SubscriptionBadge[];
tier2: SubscriptionBadge[];
} | null;
FTK: string;
BPCBANNER: boolean;
BPCCHATPOPBANNER: boolean;
BPCTIMEBANNER: boolean;
BPCPOSTROLL: string;
BPCPREROLL: string;
MIDROLL: {
VALUE: string;
OFFSET_START_TIME: number;
OFFSET_END_TIME: number;
};
PREROLLTAG: string;
MIDROLLTAG: string;
POSTROLLTAG: string;
BJAWARD: false;
BJAWARDWATERMARK: false;
BJAWARDYEAR: string;
GEM: boolean;
GEM_LOG: boolean;
CLEAR_MODE_CATE: string[];
PLAYTIMINGBUFFER_DURATION: string;
STREAMER_PLAYTIMINGBUFFER_DURATION: string;
MAXBUFFER_DURATION: string;
LOWBUFFER_DURATION: string;
PLAYBACKRATEDELTA: string;
MAXOVERSEEKDURATION: string;
};
};
type SubscriptionBadge = {
MONTH: number;
FILENAME: string;
};
declare class Logger {
name: string;
isEnabled: boolean;
constructor(name: string, isEnabled: boolean);
verbose: (msg?: any, ...optionalParams: any[]) => void;
info: (msg?: any, ...optionalParams: any[]) => void;
warn: (msg?: any, ...optionalParams: any[]) => void;
}
declare enum ServiceCommand {
PING = 0,// 접속 유지
LOGIN = 1,// 로그인
JOIN = 2,// 입장
JOINPART_USER = 4,// 열혈팬 입장/유저 강퇴
USER_TIMEOUT = 8,// 채금
CHAT = 5,// 일반 채팅
CHAT_OGQ = 109,// OGQ스티커 채팅
OGQ_GIFT = 118,// OGQ스티커 선물
SET_USERFLAG = 12,// 유저플래그 변경됨
INOUT_MANAGER = 13,// 매니저 임명/해임
SUBNICKNAME = 14,// 채팅방 닉네임 설정
ICE1 = 19,// 얼리기
ICE2 = 21,// 얼리기
SLOWMODE = 23,// 저속모드
BALLOON = 18,// 별풍선
BALLOON_AD = 87,// 애드벌룬
BALLOON_AD_STATION = 107,// 방송국 별풍선
POLL = 50,// 투표
BLOCK_WORDS_LIST = 54,// [ '', '', '' ]
STREAM_CLOSED = 88,// 뱅종
SUBSCRIPTION_NEW = 91,// 신규 구독
SUBSCRIPTION = 93,// 구독 연장
SUBSCRIPTION_GIFT = 108,// 구독권 선물
SYSTEM_NOTICE = 58,// 별별 수다 이런거 공지
CHANNEL_NOTICE = 104,// 채팅 공지
MISSION = 121
}
declare enum Userflag1 {
HOST = 2,// 방장
FANCLUB = 5,// 팬클럽
MANAGER1 = 6,// 매니저
MANAGER2 = 8,// 매니저
FEMALE = 9,// 여성
TIMEOUT_BY_DOBAE1 = 11,// 도배 채금
TIMEOUT_BY_DOBAE2 = 12,// 도배 채금
TIMEOUT_BY_DOBAE3 = 24,// 도배 채금
MOBILE = 14,// 모바일 접속
TOPFAN = 15,// 열혈
DM_BLCOKED = 17,// 귓속말 차단
QUICKVIEW = 19,// 퀵뷰
MOBILE_WEB = 23,// 모바일 웹 접속
FOLLOWER = 28
}
declare enum Userflag2 {
SUBSCRIPTION_TIER1 = 18,// 1티어 구독
SUBSCRIPTION_TIER2 = 19,// 2티어 구독
SUBSCRIPTION_TIER3 = 20
}
declare enum IceFlag {
FANCLUB = 5,// 팬클럽
SUPPORTER = 6,// 서포터
TOPFAN = 7,// 열혈팬
SUBSCRIPTION = 8,// 구독팬
MANAGER = 9
}
declare enum ConnectedState {
STANDBY = 0,
CONNECTED = 1,
JOINED = 2
}
type ConnectionInfo = {
channelId: string;
host: string;
port: number;
password: string;
};
type ChannelEmoteInfo = {
title: string;
tier: 1 | 2 | 3;
pcImg: string;
pcAltImg: string;
mobileImg: string;
mobileAltImg: string;
isAnimated: boolean;
orderNo: string;
blackKeyword: boolean;
};
type SoopChatMessage = {
content: string;
parsedContent: SoopChatMessageContent[];
emotes: Record<string, ChannelEmoteInfo>;
channelId: string;
userId: string;
normalColor: string;
language: string;
userType: string;
nickname: string;
subscription: number;
isStreamer: boolean;
isFan: boolean;
isTopfan: boolean;
isManager: boolean;
isFemale: boolean;
color: string;
colorDarkmode: string;
userflag1: number;
userflag2: number;
stickerUrl: string;
};
type SoopChatMessageContent = SoopChatMessageContentText | SoopChatMessageContentEmote;
type SoopChatMessageContentText = {
type: SoopChatMessageContentType.TEXT;
body: string;
};
type SoopChatMessageContentEmote = {
type: SoopChatMessageContentType.EMOTE;
body: string;
};
declare enum SoopChatMessageContentType {
TEXT = 0,
EMOTE = 1
}
declare enum SoopBalloonType {
NORMAL = 0,
AD = 1,
VOD = 2
}
type SoopBalloon = {
type: SoopBalloonType;
userId: string;
nickname: string;
count: number;
fanClubOrder: number;
isStation: boolean;
imageName: string;
ttsType: string;
};
declare enum SoopBlockType {
TIMEOUT = 0,
KICK = 1
}
type SoopBlock = {
type: SoopBlockType;
duration: number;
userId: string;
nickname: string;
by: string;
};
interface SoopChatClientEvents {
join: (channelId: string) => void;
part: (channelId: string) => void;
chat: (chat: SoopChatMessage) => void;
balloon: (balloon: SoopBalloon) => void;
block: (block: SoopBlock) => void;
}
declare class SoopChatClient extends TypedEmitter<SoopChatClientEvents> {
protected socket: WebSocket | null;
protected log: Logger;
protected _connection: ConnectionInfo | null;
protected set connection(connection: ConnectionInfo | null);
get connection(): ConnectionInfo | null;
protected _stream: StreamInfoOnline | null;
protected set stream(stream: StreamInfoOnline | null);
get stream(): StreamInfoOnline | null;
protected _emotes: Record<string, ChannelEmoteInfo>;
protected set emotes(emotes: Record<string, ChannelEmoteInfo>);
get emotes(): Record<string, ChannelEmoteInfo>;
private _connectedState;
protected set connectedState(state: ConnectedState);
get connectedState(): ConnectedState;
protected loopPingPong: NodeJS.Timeout;
protected decoder: TextDecoder;
constructor({ logging }: {
logging?: boolean | undefined;
});
protected sendPing: () => void;
connect: (userId: string, password?: string) => Promise<void>;
disconnect: () => void;
/**
* @deprecated
*/
close: () => void;
send: (serviceCommand: ServiceCommand, body: string) => boolean;
protected loadEmotes: (userId: string) => Promise<void>;
protected joinChannel: () => void;
protected processMessage: (msg: ArrayBuffer) => void;
protected onMsgJoin: (bodyParted: string[]) => void;
protected onMsgJoinPartUser: (bodyParted: string[]) => void;
protected onMsgSetUserTimeout: (bodyParted: string[]) => void;
protected onMsgChatMsg: (bodyParted: string[]) => void;
protected parseContent: (content: string, isSubscriber: boolean) => [SoopChatMessageContent[], Record<string, ChannelEmoteInfo>];
protected onMsgChatOgq: (bodyParted: string[]) => void;
protected onMsgOgqGift: (bodyParted: string[]) => void;
protected onMsgSetUserflag: (bodyParted: string[]) => void;
protected onMsgInoutManager: (bodyParted: string[]) => void;
protected onMsgIce: (bodyParted: string[]) => void;
protected onMsgSlowMode: (bodyParted: string[]) => void;
protected onMsgBalloon: (bodyParted: string[]) => void;
protected onMsgBalloonAd: (bodyParted: string[]) => void;
protected onMsgBalloonAdStation: (bodyParted: string[]) => void;
protected onMsgPoll: (bodyParted: string[]) => void;
protected onMsgBlockWordsList: (bodyParted: string[]) => void;
protected onMsgStreamClosed: (_: string[]) => void;
protected onMsgNoticeSystem: (bodyParted: string[]) => void;
protected onMsgNotice: (bodyParted: string[]) => void;
protected onMsgSubscriptionGift: (bodyParted: string[]) => void;
protected onMsgSubscriptionNew: (bodyParted: string[]) => void;
protected onMsgSubscription: (bodyParted: string[]) => void;
protected isUserflag: (flagName: Userflag1 | Userflag2, userflag: number) => boolean;
protected isIceflag: (flagName: IceFlag, iceflag: number) => boolean;
}
export { type ChannelEmoteInfo, ConnectedState, type ConnectionInfo, type SoopBalloon, SoopBalloonType, type SoopBlock, SoopBlockType, SoopChatClient, type SoopChatMessage, type SoopChatMessageContent, type SoopChatMessageContentEmote, type SoopChatMessageContentText, SoopChatMessageContentType, type StreamInfoOnline };