Compare commits

..

No commits in common. "master" and "v0.1.1-alpha" have entirely different histories.

61 changed files with 278 additions and 19118 deletions

5
.env
View File

@ -1,5 +0,0 @@
FLASK_ENV=development
FLASK_DEBUG=False
FLASK_RUN_PORT=5000
FLASK_RUN_HOST=0.0.0.0
FLASK_APP=WebMain.py

183
.gitignore vendored
View File

@ -1,183 +0,0 @@
# Created by .ignore support plugin (hsz.mobi)
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
### VirtualEnv template
# Virtualenv
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
.Python
[Bb]in
[Ii]nclude
[Ll]ib
[Ll]ib64
[Ll]ocal
[Ss]cripts
pyvenv.cfg
.venv
pip-selfcheck.json
*.mp4
*.flv
config*
.*

View File

@ -1,2 +0,0 @@
# 接口版本9.4.2(94214)
弹幕接口改为`/webcast/im/fetch/`发现会先连接websocket然而websocket又是魔改protobuf实在是弄不懂

23
Chat.py Normal file
View File

@ -0,0 +1,23 @@
from User import User
class Chat:
content:str=""
user:User=None
def __init__(self, json=None):
if json:
self.parse(json)
def parse(self, json):
self.user = User(json)
if "Msg" in json:
if "content" in json["Msg"]:
self.content = json["Msg"]['content']
def __str__(self):
return "{} : {}".format(self.user,self.content)
def __unicode__(self):
return self.__str__()

478
Common.py
View File

@ -1,478 +0,0 @@
import os
import queue
from datetime import datetime, timedelta
import psutil
from api import XiGuaLiveApi
import json
import threading
from bilibili import Bilibili, VideoPart
# 默认设置
config = {
# 录像的主播ID
"l_u": "97621754276",
# 视频位置
"path": ".",
# 标题及预留时间位置
"t_t": "【永恒de草薙直播录播】直播于 {}",
# 标签
"tag": ["永恒de草薙", "三国", "三国战记", "直播录像", "录播", "怀旧", "街机"],
# 描述
"des": "西瓜直播 https://live.ixigua.com/userlive/97621754276 \n自动投递\n原主播永恒de草薙\n直播时间晚上6点多到凌晨4点左右",
# 来源, 空则为自制
"src": "",
# Log条数
"l_c": 5,
# 错误Log条数
"elc": 10,
# 每一chunk大小
"c_s": 16 * 1024,
# 每一块视频大小
"p_s": 2141000000,
# 忽略的大小
"i_s": 2048000,
"max": 75,
"dow": "echo 'clean'",
# 仅下载
"dlO": True,
# 下播延迟投稿
"dly": 30,
# 短的时间的格式
"sdf": "%Y%m%d",
"enc": "ffmpeg -i {f} -c:v copy -c:a copy -f mp4 {t} -y"
}
doCleanTime = datetime.fromtimestamp(0)
loginTime = datetime.fromtimestamp(0)
_clean_flag = None
delay = datetime.fromtimestamp(0)
b = Bilibili()
network = [{
"currentTime": datetime.now(),
"out": {
"currentByte": psutil.net_io_counters().bytes_sent,
},
"in": {
"currentByte": psutil.net_io_counters().bytes_recv,
}
}, {
"currentTime": datetime.now(),
"out": {
"currentByte": psutil.net_io_counters().bytes_sent,
},
"in": {
"currentByte": psutil.net_io_counters().bytes_recv,
}
}]
def reloadConfig():
global config
if os.path.exists('config.json'):
_config_fp = open("config.json", "r", encoding="utf8")
_config = json.load(_config_fp)
config.update(_config)
_config_fp.close()
def resetDelay():
global delay
delay = datetime.now() + timedelta(minutes=int(config['dly']))
def doDelay():
global delay
if -60 < getTimeDelta(datetime.now(), delay) < 60:
delay = datetime.fromtimestamp(0)
return True
return False
def updateNetwork():
global network
network.append({
"currentTime": datetime.now(),
"out": {
"currentByte": psutil.net_io_counters().bytes_sent,
},
"in": {
"currentByte": psutil.net_io_counters().bytes_recv,
}
})
network = network[-3:]
def getTimeDelta(a, b):
return (a - b).total_seconds()
def _doClean(_force=False):
global doCleanTime, _clean_flag
_disk = psutil.disk_usage(".")
if _disk.percent > config["max"] or _force:
_clean_flag = True
doCleanTime = datetime.now()
appendOperation("执行配置的清理命令")
os.system(config["dow"])
appendOperation("执行配置的清理命令完毕")
doCleanTime = datetime.now()
_clean_flag = False
def doClean(_force=False):
if _clean_flag:
return
p = threading.Thread(target=_doClean, args=(_force,))
p.setDaemon(True)
p.start()
def getCurrentStatus():
_disk = psutil.disk_usage(".")
_mem = psutil.virtual_memory()
_net = psutil.net_io_counters()
_delta = getTimeDelta(network[-1]["currentTime"], network[-2]["currentTime"])
if 60 > _delta > 1:
_inSpeed = (network[-1]["in"]["currentByte"] - network[-2]["in"]["currentByte"]) / _delta
_outSpeed = (network[-1]["out"]["currentByte"] - network[-2]["out"]["currentByte"]) / _delta
else:
_outSpeed = (network[-1]["in"]["currentByte"] - network[-2]["in"]["currentByte"])
_inSpeed = (network[-1]["out"]["currentByte"] - network[-2]["out"]["currentByte"])
updateNetwork()
return {
"memTotal": parseSize(_mem.total),
"memUsed": parseSize(_mem.used),
"memUsage": _mem.percent,
"diskTotal": parseSize(_disk.total),
"diskUsed": parseSize(_disk.used),
"diskUsage": _disk.percent,
"cpu": psutil.cpu_percent(),
"outSpeed": parseSize(_outSpeed),
"inSpeed": parseSize(_inSpeed),
"doCleanTime": datetime.strftime(doCleanTime, dt_format),
}
dt_format = "%Y/%m/%d %H:%M:%S"
reloadConfig()
broadcaster = ""
streamUrl = ""
forceNotDownload = False
forceNotBroadcasting = False
forceNotUpload = False
forceNotEncode = False
if config["dlO"] is True:
forceNotUpload = True
forceNotEncode = True
forceStartEncodeThread = False
forceStartUploadThread = False
uploadQueue = queue.Queue()
encodeQueue = queue.Queue()
uploadStatus = []
downloadStatus = []
encodeStatus = []
errors = []
operations = []
def appendOperation(obj):
global operations
if isinstance(obj, dict):
if "datetime" not in obj:
obj["datetime"] = datetime.strftime(datetime.now(), dt_format)
operations.append(obj)
else:
operations.append({
"datetime": datetime.strftime(datetime.now(), dt_format),
"message": str(obj)
})
operations = operations[-config["elc"]:]
def parseSize(size):
K = size / 1024.0
if K > 1000:
M = K / 1024.0
if M > 1000:
return "{:.2f}GB".format(M / 1024.0)
else:
return "{:.2f}MB".format(M)
else:
return "{:.2f}KB".format(K)
def appendUploadStatus(obj):
global uploadStatus
if isinstance(obj, dict):
if "datetime" not in obj:
obj["datetime"] = datetime.strftime(datetime.now(), dt_format)
uploadStatus.append(obj)
else:
uploadStatus.append({
"datetime": datetime.strftime(datetime.now(), dt_format),
"message": str(obj)
})
uploadStatus = uploadStatus[-config["l_c"]:]
def modifyLastUploadStatus(obj):
global uploadStatus
if isinstance(obj, dict):
if "datetime" not in obj:
obj["datetime"] = datetime.strftime(datetime.now(), dt_format)
uploadStatus[-1] = obj
else:
uploadStatus[-1]["message"] = str(obj)
uploadStatus[-1]["datetime"] = datetime.strftime(datetime.now(), dt_format)
def appendEncodeStatus(obj):
global encodeStatus
if isinstance(obj, dict):
if "datetime" not in obj:
obj["datetime"] = datetime.strftime(datetime.now(), dt_format)
encodeStatus.append(obj)
else:
encodeStatus.append({
"datetime": datetime.strftime(datetime.now(), dt_format),
"message": str(obj)
})
encodeStatus = encodeStatus[-config["l_c"]:]
def modifyLastEncodeStatus(obj):
global encodeStatus
if isinstance(obj, dict):
if "datetime" not in obj:
obj["datetime"] = datetime.strftime(datetime.now(), dt_format)
encodeStatus[-1] = obj
else:
encodeStatus[-1]["message"] = str(obj)
encodeStatus[-1]["datetime"] = datetime.strftime(datetime.now(), dt_format)
def appendDownloadStatus(obj):
global downloadStatus
if isinstance(obj, dict):
if "datetime" not in obj:
obj["datetime"] = datetime.strftime(datetime.now(), dt_format)
downloadStatus.append(obj)
else:
downloadStatus.append({
"datetime": datetime.strftime(datetime.now(), dt_format),
"message": str(obj)
})
downloadStatus = downloadStatus[-config["l_c"]:]
def modifyLastDownloadStatus(obj):
global downloadStatus
if isinstance(obj, dict):
if "datetime" not in obj:
obj["datetime"] = datetime.strftime(datetime.now(), dt_format)
downloadStatus[-1] = obj
else:
downloadStatus[-1]["message"] = str(obj)
downloadStatus[-1]["datetime"] = datetime.strftime(datetime.now(), dt_format)
def appendError(obj):
global errors
if isinstance(obj, dict):
if "datetime" not in obj:
obj["datetime"] = datetime.strftime(datetime.now(), dt_format)
errors.append(obj)
else:
errors.append({
"datetime": datetime.strftime(datetime.now(), dt_format),
"message": str(obj)
})
errors = errors[-config["elc"]:]
def loginBilibili(force=False):
if config["dlO"] is False or forceNotUpload is False:
global loginTime
global b
if getTimeDelta(datetime.now(), loginTime) < 86400 * 10 and not force:
return False
try:
b.login()
loginTime = datetime.now()
return True
except Exception as e:
appendError(e)
appendOperation("登录失败")
return False
else:
appendOperation("设置了不上传,所以不会登陆")
class downloader(XiGuaLiveApi):
__playlist = None
__danmakuFile = None
__danmakuBiasTime = None
def getDanmaku(self):
super(downloader, self).getDanmaku()
if self.__danmakuFile is not None and self.__danmakuFile.writable():
self.__danmakuFile.flush()
def onPresentEnd(self, gift):
if self.__danmakuFile is not None and self.__danmakuFile.writable():
now = datetime.now()
if self.__danmakuBiasTime is None:
return
ts = (now - self.__danmakuBiasTime).total_seconds()
_c = """<gift ts="{:.2f}" user="{}" giftname="{}" giftcount="{}"></gift>\r\n""".format(ts, gift.user.name, gift.name, gift.count)
self.__danmakuFile.write(_c.encode("UTF-8"))
def onChat(self, chat):
if self.__danmakuFile is not None and self.__danmakuFile.writable():
now = datetime.now()
if self.__danmakuBiasTime is None:
return
ts = (now - self.__danmakuBiasTime).total_seconds()
_c = """<d p="{:.2f},1,24,16777215,{:.0f},0,{},0" user="{}">{}</d>\r\n""".format(ts, now.timestamp()*1000, chat.user.ID, chat.user.name, chat.content)
self.__danmakuFile.write(_c.encode("UTF-8"))
@property
def playlist(self):
return self.__playlist
@playlist.setter
def playlist(self, value):
global streamUrl
self.__playlist = value
streamUrl = value
def _checkUsernameIsMatched(self, compare=None):
return True
def updRoomInfo(self, force=False):
global broadcaster
_prev_status = self.isLive
doClean()
if not force and self.isLive:
return _prev_status
_result = super(downloader, self).updRoomInfo(force)
if _prev_status != self.isLive and not self.isLive:
# 及时保存
self.__danmakuFile.close()
self.__danmakuFile = None
self.__danmakuBiasTime = None
resetDelay()
broadcaster = self.broadcaster
if _result:
if self.isLive:
self.updPlayList()
else:
self.playlist = False
return _result
def updPlayList(self):
if self.isLive and "stream_url" in self._rawRoomInfo:
if 'rtmp_pull_url' in self._rawRoomInfo["stream_url"]:
self.playlist = self._rawRoomInfo["stream_url"]['rtmp_pull_url']
elif 'flv_pull_url' in self._rawRoomInfo["stream_url"]:
_playlist = self._rawRoomInfo["stream_url"]["flv_pull_url"]
if type(_playlist) is dict:
for _ in _playlist.values():
self.playlist = _
break
self.playlist = self.playlist.replace("_hd5", "").replace("_sd5", "").replace("_ld5", "").replace("_md", "")
else:
self.playlist = None
def initSave(self, f):
if self.__danmakuFile is not None and not self.__danmakuFile.closed:
self.__danmakuFile.close()
self.__danmakuBiasTime = datetime.now()
self.__danmakuFile = open(f, "wb")
api = downloader(config["l_u"])
def doUpdatePlaylist(_force=False):
p = threading.Thread(target=api.updRoomInfo, args=(_force,))
p.setDaemon(True)
p.start()
def refreshDownloader():
global api
api = downloader(config["l_u"])
def uploadVideo(name):
if not os.path.exists(name):
appendError("Upload File Not Exist {}".format(name))
return
loginBilibili()
doClean()
if forceNotUpload is False:
b.preUpload(VideoPart(path=name, title=os.path.basename(name)))
else:
appendUploadStatus("设置了不上传,所以[{}]不会上传了".format(name))
if not forceNotEncode:
os.remove(name)
def publishVideo(date):
if forceNotUpload is False:
b.finishUpload(config["t_t"].format(date), 17, config["tag"], config["des"],
source=config["src"], no_reprint=0)
b.clear()
else:
appendUploadStatus("设置了不上传,所以[{}]的录播不会投了".format(date))
def encodeVideo(name):
if forceNotEncode:
appendEncodeStatus("设置了不编码,所以[{}]不会编码".format(name))
return False
if not os.path.exists(name):
appendEncodeStatus("文件[{}]不存在".format(name))
return False
if os.path.getsize(name) < 8 * 1024 * 1024:
appendEncodeStatus("Encoded File >{}< is too small, will ignore it".format(name))
return False
appendEncodeStatus("Encoding >{}< Start".format(name))
_new_name = os.path.splitext(name)[0] + ".mp4"
_code = os.system(config["enc"].format(f=name, t=_new_name))
if _code != 0:
appendError("Encode {} with Non-Zero Return.".format(name))
return False
modifyLastEncodeStatus("Encode >{}< Finished".format(name))
uploadQueue.put(_new_name)
def collectInfomation():
return {
"download": downloadStatus,
"encode": encodeStatus,
"encodeQueueSize": encodeQueue.qsize(),
"upload": uploadStatus,
"uploadQueueSize": uploadQueue.qsize(),
"error": errors,
"operation": operations,
"broadcast": {
"broadcaster": broadcaster.__str__(),
"isBroadcasting": api.isLive,
"streamUrl": streamUrl,
"updateTime": api.updateAt.strftime(dt_format),
"delayTime": delay.strftime(dt_format)
},
"config": {
"forceNotBroadcasting": forceNotBroadcasting,
"forceNotDownload": forceNotDownload,
"forceNotUpload": forceNotUpload,
"forceNotEncode": forceNotEncode,
"downloadOnly": config['dlO'],
},
}

Binary file not shown.

View File

@ -1,15 +0,0 @@
syntax = "proto2";
message XiguaLive {
message Data {
// WebcastChatMessage
// WebcastGiftMessage
required string method = 1;
required bytes raw = 2;
}
repeated Data data = 1;
required string cursor = 2;
optional int32 fetch_interval = 3;
optional int32 now = 4;
required string internal_ext = 5;
}

View File

@ -1,10 +0,0 @@
syntax = "proto2";
//
message Gift {
required string id = 1;
required string name = 2;
}
message GiftPack {
required int32 id = 1;
required Gift gift = 2;
}

View File

@ -1,89 +0,0 @@
syntax = "proto2";
import "XiguaUser.proto";
import "XiguaGift.proto";
message Message {
required CommonInfo commonInfo = 1;
}
message FansClubMessage {
required CommonInfo commonInfo = 1;
// 12
required int32 type = 2;
//
required string content = 3;
required User user = 4;
}
message FansClubStatsMessage {
required CommonInfo commonInfo = 1;
required string title = 2;
required int32 count = 3;
}
message UserSeqMessage {
required CommonInfo commonInfo = 1;
required string popularityText = 4;
required int32 popularity = 6;
}
message DailyRankMessage {
required CommonInfo commonInfo = 1;
required int32 ranking = 10;
}
message ChatMessage {
required CommonInfo commonInfo = 1;
required User user = 2;
required string content = 3;
}
message MemberMessage {
required CommonInfo commonInfo = 1;
required User user = 2;
required string popularityText = 14;
}
message GiftMessage {
required CommonInfo commonInfo = 1;
required int32 giftId = 2;
// GroupId之类的东西
// required int32 UNKNOWN_INT = 3;
required int32 content4 = 4;
required int32 repeated = 5;
required int32 combo = 6;
optional User user = 7;
//
optional bool isFinished = 9 [ default = false ];
}
message SocialMessage {
required CommonInfo commonInfo = 1;
required User user = 2;
required int32 int4 = 4;
required int32 fansCount = 6;
}
//
message Style {
optional string color = 1;
optional int32 fontWeight = 4;
}
//
message Params {
// 1
// 11
// 12
required int32 type = 1;
optional Style style = 2;
optional string string = 11;
optional UserPack users = 21;
optional GiftPack gifts = 22;
}
//
message DisplayText {
//
required string method = 1;
required string format = 2;
optional Style bgStyle = 3;
required Params params = 4;
}
//
message CommonInfo {
required string method = 1;
required int32 msg_id = 2;
required int32 room_id = 3;
required int32 create_time = 4;
optional int32 someEnum = 6;
optional DisplayText displayText = 8;
}

View File

@ -1,81 +0,0 @@
syntax = "proto2";
message UserPack {
required User user = 1;
}
//
message Badge {
message FanClubText {
required string text = 1;
optional string color = 2;
required int32 level = 3;
}
repeated string url = 1;
// optional string localUrl = 2;
optional int32 height = 3;
optional int32 width = 4;
// 3
// 6
// 7
optional int32 type = 6;
optional string clickTo = 7;
optional FanClubText fanClubText = 8;
}
message FansClubPack {
message FansClub {
required string title = 1 [default = ''];
required int32 level = 2 [default = 0];
optional int32 someEnum = 3;
}
required FansClub fansClub = 1;
}
//
message User {
//
message Avatar {
required string url = 1;
optional string id = 2;
}
//
message Follow {
optional int32 following = 1 [default = 0];
optional int32 follower = 2 [default = 0];
}
//
message PayGrade {
required int32 current = 1;
required int32 level = 6;
optional int32 currentLevelNeed = 10;
optional int32 nextLevelNeed = 11;
optional string content = 13;
required Badge badge = 19;
optional int32 toNextLevelNeed = 21;
}
//
message HonorLevel {
required Badge badge = 19;
}
//
message Noble {
message NobleBoarder {
repeated string urlList = 1;
required string uri = 2;
optional int32 height = 3;
optional int32 width = 4;
}
required string content = 4;
optional NobleBoarder boarder = 8;
}
required int64 id = 1;
required string nickname = 3;
required int32 gender = 4;
//
required Avatar avatarThumb = 9;
optional Avatar avatarMedium = 10;
optional Avatar avatarLarge = 11;
repeated Badge badge = 21;
optional Follow follow = 22;
required PayGrade payGrade = 23;
required FansClubPack fansClub = 24;
required int32 totalPaid = 34;
}

Binary file not shown.

Binary file not shown.

View File

@ -1,997 +0,0 @@
1 {
1: "WebcastGiftMessage"
2 {
1 {
1: "WebcastGiftMessage"
2: 6787717978657360643
3: 6787691314156276488
4: 1580388803763
6: 1
8 {
1: "webcast_xigua_gift_message"
2: "{0:user} \351\200\201\347\273\231\344\270\273\346\222\255{2:string}\344\270\252{1:gift}"
3 {
1: "#ffff9d5c"
4: 400
}
4 {
1: 11
2 {
1: "#ffffd600"
4: 400
}
21 {
1 {
1: 105855829073
3: "\345\260\217\350\234\234\346\237\240\346\252\254\350\214\266"
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
10 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
11 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
15: 1
21 {
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_5.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
21 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_14.png"
6: 7
8 {
1: "\346\260\270\346\201\222"
2: "#FFFFFF"
3: 14
}
}
22 {
1: 2
2: 1
}
23 {
1: 62
6: 5
10: 51
11: 99
13: "\350\267\235\347\246\2736\347\272\247\350\277\230\345\267\25638\351\222\273\347\237\263"
19 {
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_5.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
21: 38
}
24 {
1 {
1: "\346\260\270\346\201\222"
2: 14
3: 1
4 {
1 {
1: 2
2 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_14.png"
3: 48
4: 150
}
}
2: "\346\260\270\346\201\222"
}
}
}
32: ""
34: 62
37: 1
38: "0"
44: ""
46: "MS4wLjABAAAAd4R7mC-c8FCTjCqTIhJ0CoydF_FMweyatdS66xud0hY"
48: ""
1028: "105855829073"
}
2: 1
}
}
4 {
1: 12
2 {
1: "#ffff9d5c"
4: 400
}
22 {
1: 10001
2 {
1: "live_gift_10001"
2: "\350\245\277\347\223\234"
}
}
}
4 {
1: 1
2 {
1: "#ffff9d5c"
4: 400
}
11: "18"
}
}
}
2: 10001
3: 4997044
4: 1
5: 18
6: 18
7 {
1: 105855829073
3: "\345\260\217\350\234\234\346\237\240\346\252\254\350\214\266"
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
10 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
11 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
15: 1
21 {
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_5.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
21 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_14.png"
6: 7
8 {
1: "\346\260\270\346\201\222"
2: "#FFFFFF"
3: 14
}
}
22 {
1: 2
2: 1
}
23 {
1: 62
6: 5
10: 51
11: 99
13: "\350\267\235\347\246\2736\347\272\247\350\277\230\345\267\25638\351\222\273\347\237\263"
19 {
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_5.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
21: 38
}
24 {
1 {
1: "\346\260\270\346\201\222"
2: 14
3: 1
4 {
1 {
1: 2
2 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_14.png"
3: 48
4: 150
}
}
2: "\346\260\270\346\201\222"
}
}
}
32: ""
34: 62
37: 1
38: "0"
44: ""
46: "MS4wLjABAAAAd4R7mC-c8FCTjCqTIhJ0CoydF_FMweyatdS66xud0hY"
48: ""
1028: "105855829073"
}
11: 1580388797
12: 7453182
}
}
1 {
1: "WebcastSocialMessage"
2 {
1 {
1: "WebcastSocialMessage"
2: 6787718225754295054
3: 6787691314156276488
4: 1580388803802
6: 1
}
2 {
1: 111036833136
3: "\347\224\250\346\210\2679627521617519"
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/3796/2975850990~120x256.image"
}
22 {
1: 1
2: 19
}
23 {
19: ""
}
24 {
1 {
4 {
1 {
1: 0
2: ""
}
}
}
}
32: ""
38: "0"
46: "MS4wLjABAAAApZHNJdD-IbL7CES631w87jSXrSyXZfqETb-HYnYx6Ug"
54: 3
}
4: 1
6: 169079
}
}
1 {
1: "WebcastGiftMessage"
2 {
1 {
1: "WebcastGiftMessage"
2: 6787718023417531148
3: 6787691314156276488
4: 1580388804048
6: 1
8 {
1: "webcast_xigua_gift_message"
2: "{0:user} \351\200\201\347\273\231\344\270\273\346\222\255{2:string}\344\270\252{1:gift}"
3 {
1: "#ffff9d5c"
4: 400
}
4 {
1: 11
2 {
1: "#ffffd600"
4: 400
}
21 {
1 {
1: 105855829073
3: "\345\260\217\350\234\234\346\237\240\346\252\254\350\214\266"
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
10 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
11 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
15: 1
21 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_5.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
21 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_14.png"
6: 7
8 {
1: "\346\260\270\346\201\222"
2: "#FFFFFF"
3: 14
}
}
22 {
1: 2
2: 1
}
23 {
1: 62
6: 5
10: 51
11: 99
13: "\350\267\235\347\246\2736\347\272\247\350\277\230\345\267\25638\351\222\273\347\237\263"
19 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_5.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
21: 38
}
24 {
1 {
1: "\346\260\270\346\201\222"
2: 14
3: 1
4 {
1 {
1: 2
2 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_14.png"
3: 48
4: 150
}
}
2: "\346\260\270\346\201\222"
}
}
}
32: ""
34: 62
37: 1
38: "0"
44: ""
46: "MS4wLjABAAAAd4R7mC-c8FCTjCqTIhJ0CoydF_FMweyatdS66xud0hY"
48: ""
1028: "105855829073"
}
2: 1
}
}
4 {
1: 12
2 {
1: "#ffff9d5c"
4: 400
}
22 {
1: 10001
2 {
1: "live_gift_10001"
2: "\350\245\277\347\223\234"
}
}
}
4 {
1: 1
2 {
1: "#ffff9d5c"
4: 400
}
11: "19"
}
}
}
2: 10001
3: 4997044
4: 1
5: 19
6: 19
7 {
1: 105855829073
3: "\345\260\217\350\234\234\346\237\240\346\252\254\350\214\266"
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
10 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
11 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
15: 1
21 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_5.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
21 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_14.png"
6: 7
8 {
1: "\346\260\270\346\201\222"
2: "#FFFFFF"
3: 14
}
}
22 {
1: 2
2: 1
}
23 {
1: 62
6: 5
10: 51
11: 99
13: "\350\267\235\347\246\2736\347\272\247\350\277\230\345\267\25638\351\222\273\347\237\263"
19 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_5.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
21: 38
}
24 {
1 {
1: "\346\260\270\346\201\222"
2: 14
3: 1
4 {
1 {
1: 2
2 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_14.png"
3: 48
4: 150
}
}
2: "\346\260\270\346\201\222"
}
}
}
32: ""
34: 62
37: 1
38: "0"
44: ""
46: "MS4wLjABAAAAd4R7mC-c8FCTjCqTIhJ0CoydF_FMweyatdS66xud0hY"
48: ""
1028: "105855829073"
}
11: 1580388797
12: 7453182
}
}
1 {
1: "WebcastRoomUserSeqMessage"
2 {
1 {
1: "WebcastRoomUserSeqMessage"
2: 6787718227533761294
3: 6787691314156276488
4: 1580388804226
}
2 {
1: 9999
2 {
1: 4719119436
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/6368/3857576856~120x256.image"
}
23: ""
54: 3
}
3: 1
}
2 {
1: 9998
2 {
1: 60374191432
2: 259345
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/da99000fd41edfb7daa6~120x256.image"
}
23: ""
54: 3
}
3: 2
}
2 {
1: 1699
2 {
1: 3544417251634206
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/830d7e15f45946aa9b757a500cc6dcbe~120x256.image"
}
23: ""
54: 3
}
3: 3
}
2 {
1: 1099
2 {
1: 4261353838881501
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/c24df9dffd6d45929c227c5da22fe406~120x256.image"
}
23: ""
54: 3
}
3: 4
}
2 {
1: 520
2 {
1: 2933125236921479
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/2e1c9d64f34a4a3e8a326fe5394659fd~120x256.image"
}
23: ""
54: 3
}
3: 5
}
2 {
1: 300
2 {
1: 3927095572170669
9 {
1: "http://p1-xg.bytecdn.cn/thumb/daaa001914e0039994ae"
2: "daaa001914e0039994ae"
}
23: ""
54: 3
}
3: 6
}
2 {
1: 120
2 {
1: 153552343543981
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/mosaic-legacy/3795/3033762272~120x256.image"
}
23: ""
54: 3
}
3: 7
}
2 {
1: 99
2 {
1: 1732418933370259
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/5941f17833524bfa9316a648c39c990f~120x256.image"
}
23: ""
54: 3
}
3: 8
}
2 {
1: 99
2 {
1: 104372509299
9 {
1: "http://p1-xg.bytecdn.cn/thumb/da920004cd041ec12061"
2: "da920004cd041ec12061"
}
23: ""
54: 3
}
3: 9
}
2 {
1: 60
2 {
1: 60518722952
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/0f9162a614bd474f9fbda57614a0c9f1~120x256.image"
}
23: ""
54: 3
}
3: 10
}
2 {
1: 30
2 {
1: 1261881879167767
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3795/3044413937~120x256.image"
}
23: ""
54: 3
}
3: 11
}
2 {
1: 22
2 {
1: 1173933315333736
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/a181c0707ff540aba16f43af049a3791~120x256.image"
}
23: ""
54: 3
}
3: 12
}
2 {
1: 20
2 {
1: 3949047076102647
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/187afa353816402cb827e9fae386ca2a~120x256.image"
}
23: ""
54: 3
}
3: 13
}
2 {
1: 2
2 {
1: 65771610619
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/3793/3131589739~120x256.image"
}
23: ""
54: 3
}
3: 14
}
2 {
2 {
1: 99827340042
9 {
1: "http://p1-xg.bytecdn.cn/thumb/da74000192436fc5db6e"
2: "da74000192436fc5db6e"
}
23: ""
54: 3
}
3: 15
}
2 {
2 {
1: 99482502045
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/mosaic-legacy/3793/3114521287~120x256.image"
}
23: ""
54: 3
}
3: 16
}
2 {
2 {
1: 98103952579
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/3793/3131589739~120x256.image"
}
23: ""
54: 3
}
3: 17
}
2 {
2 {
1: 9746464842
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/6ad34237256e4471b16810eb098224c0~120x256.image"
}
23: ""
54: 3
}
3: 18
}
2 {
2 {
1: 97221408269
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/3793/3131589739~120x256.image"
}
23: ""
54: 3
}
3: 19
}
2 {
2 {
1: 971618215795604
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3797/2889309425~120x256.image"
}
23: ""
54: 3
}
3: 20
}
3: 461
4: "15\344\270\207\344\272\272\346\260\224"
6: 158310
}
}
1 {
1: "WebcastGiftMessage"
2 {
1 {
1: "WebcastGiftMessage"
2: 6787717971278351115
3: 6787691314156276488
4: 1580388804414
6: 1
8 {
1: "webcast_xigua_gift_message"
2: "{0:user} \351\200\201\347\273\231\344\270\273\346\222\255{2:string}\344\270\252{1:gift}"
3 {
1: "#ffff9d5c"
4: 400
}
4 {
1: 11
2 {
1: "#ffffd600"
4: 400
}
21 {
1 {
1: 105855829073
3: "\345\260\217\350\234\234\346\237\240\346\252\254\350\214\266"
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
10 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
11 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
15: 1
21 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_5.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
21 {
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_14.png"
6: 7
8 {
1: "\346\260\270\346\201\222"
2: "#FFFFFF"
3: 14
}
}
22 {
1: 2
2: 1
}
23 {
1: 62
6: 5
10: 51
11: 99
13: "\350\267\235\347\246\2736\347\272\247\350\277\230\345\267\25638\351\222\273\347\237\263"
19 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_5.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
21: 38
}
24 {
1 {
1: "\346\260\270\346\201\222"
2: 14
3: 1
4 {
1 {
1: 2
2 {
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_14.png"
3: 48
4: 150
}
}
2: "\346\260\270\346\201\222"
}
}
}
32: ""
34: 62
37: 1
38: "0"
44: ""
46: "MS4wLjABAAAAd4R7mC-c8FCTjCqTIhJ0CoydF_FMweyatdS66xud0hY"
48: ""
1028: "105855829073"
}
2: 1
}
}
4 {
1: 12
2 {
1: "#ffff9d5c"
4: 400
}
22 {
1: 10001
2 {
1: "live_gift_10001"
2: "\350\245\277\347\223\234"
}
}
}
4 {
1: 1
2 {
1: "#ffff9d5c"
4: 400
}
11: "20"
}
}
}
2: 10001
3: 4997044
4: 1
5: 20
6: 20
7 {
1: 105855829073
3: "\345\260\217\350\234\234\346\237\240\346\252\254\350\214\266"
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
10 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
11 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
15: 1
21 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_5.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
21 {
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_14.png"
6: 7
8 {
1: "\346\260\270\346\201\222"
2: "#FFFFFF"
3: 14
}
}
22 {
1: 2
2: 1
}
23 {
1: 62
6: 5
10: 51
11: 99
13: "\350\267\235\347\246\2736\347\272\247\350\277\230\345\267\25638\351\222\273\347\237\263"
19 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_5.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
21: 38
}
24 {
1 {
1: "\346\260\270\346\201\222"
2: 14
3: 1
4 {
1 {
1: 2
2 {
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_14.png"
3: 48
4: 150
}
}
2: "\346\260\270\346\201\222"
}
}
}
32: ""
34: 62
37: 1
38: "0"
44: ""
46: "MS4wLjABAAAAd4R7mC-c8FCTjCqTIhJ0CoydF_FMweyatdS66xud0hY"
48: ""
1028: "105855829073"
}
11: 1580388797
12: 7453184
}
}
2: "6787717971278351115_1580388804554_6787718002764073739_1"
3: 1000
4: 1580388804554
5: "fetch_time:1580388804554|start_time:1580388804048|ack_ids:6787718023417531148_1b2|fetch_id:6787718004823608078|flag:1|seq:141"

View File

@ -1,165 +0,0 @@
1 {
1: "WebcastMemberMessage"
2 {
1 {
1: "WebcastMemberMessage"
2: 6787727734057011981
3: 6787691314156276488
6: 1
8 {
1: "member_silence_toast_3"
2: "{0:user} \350\242\253\347\256\241\347\220\206\345\221\230 {1:user} \347\246\201\350\250\200\344\272\206"
3 {
1: "#de000000"
4: 400
}
4 {
1: 11
2 {
1: "#61000000"
4: 400
}
21 {
1 {
1: 53536270159
3: "\350\243\244\350\243\206\351\207\214\347\232\204\345\244\247\345\256\235\345\211\221"
38: "0"
46: "MS4wLjABAAAAtH9p-LupXO1oQVJtlefmpryPoXqWzKs3_Nad9BlAREA"
}
}
}
4 {
1: 11
2 {
1: "#61000000"
4: 400
}
21 {
1 {
1: 2721997823950523
3: "\350\257\267\345\217\253\346\210\221\347\226\257\345\255\220\345\205\255"
38: "0"
46: "MS4wLjABAAAA1KKMtPQlRg_wecgX0G2Wl-ZIcWe-Yos95-IBwF1AzhSYzL5-zXCa4lciHj2HZho5"
}
}
}
}
}
2 {
1: 53536270159
3: "\350\243\244\350\243\206\351\207\214\347\232\204\345\244\247\345\256\235\345\211\221"
4: 1
9 {
1: "http://p3-xg.bytecdn.cn/thumb/1bf40000bd6dc5335b2d"
2: "1bf40000bd6dc5335b2d"
}
21 {
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_9.png~tplv-obj.png"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_9.png~tplv-obj.png"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_9.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_9.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
21 {
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_7.png~tplv-obj.image"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_7.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_7.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_7.png"
6: 7
8 {
1: "\346\260\270\346\201\222"
2: "#FFFFFF"
3: 7
}
}
22 {
1: 1
2: 17
}
23 {
6: 9
19 {
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_9.png~tplv-obj.png"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_9.png~tplv-obj.png"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_9.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_9.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
}
24 {
1 {
1: "\346\260\270\346\201\222"
2: 7
3: 1
4 {
1 {
1: 2
2 {
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_7.png~tplv-obj.image"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_7.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_7.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_7.png"
3: 48
4: 150
}
}
2: "\346\260\270\346\201\222"
}
}
}
32 {
1: 1
}
38: "0"
46: "MS4wLjABAAAAtH9p-LupXO1oQVJtlefmpryPoXqWzKs3_Nad9BlAREA"
50 {
1 {
3: 1008
4: 1125
}
3 {
3: 105
4: 111
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fnoble%2Fnoble_privilege_intro%2Findex.html%3Fforbid_right_back%3D1&type=fullscreen&hide_nav_bar=1&status_bar_color=white&status_bar_bg_color=%2300000000&noble_intercept=1&__live_platform__=webcast"
}
4: "\346\231\256\351\200\232\347\224\250\346\210\267"
6 {
3: 366
4: 615
}
7 {
3: 60
4: 108
}
8 {
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/noble_boarder.png~tplv-obj.image"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/noble_boarder.png~tplv-obj.image"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/noble_boarder.png~tplv-obj.image"
2: "webcast/noble_boarder.png"
3: 64
4: 64
}
}
54: 3
}
3: 555
4 {
1: 2721997823950523
3: "\350\257\267\345\217\253\346\210\221\347\226\257\345\255\220\345\205\255"
38: "0"
46: "MS4wLjABAAAA1KKMtPQlRg_wecgX0G2Wl-ZIcWe-Yos95-IBwF1AzhSYzL5-zXCa4lciHj2HZho5"
}
10: 9
14: "16\344\270\207\344\272\272\346\260\224"
}
}
2: "6787727734057011981_1580391018357_6787727537927867150_1"
3: 1000
4: 1580391018357
5: "fetch_time:1580391018357|start_time:1580391017508|ack_ids:6787727734057011981_1296|fetch_id:6787727723432626957|flag:1|seq:126"

View File

@ -1,605 +0,0 @@
1 {
1: "WebcastChatMessage"
2 {
1 {
1: "WebcastChatMessage"
2: 6776883976293452551
3: 6776859660747344653
4: 1577866267927
6: 1
8 {
1: "webcast_chat_display_text"
2: "{0:user}{1:string}"
3 {
1: "#ff36c0cf"
4: 400
}
4 {
1: 11
2 {
1: "#60000000"
4: 400
}
21 {
1 {
1: 51510235218
3: "\351\222\242\346\236\252\345\205\204\345\274\237\350\266\205\345\223\245"
4: 1
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/2e8b032f45854441bd5e539ea892e00f~120x256.image"
}
21 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_admin_badge_v2.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_admin_badge_v2.png~tplv-obj.image"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_admin_badge_v2.png~tplv-obj.image"
2: "webcast/xigua_admin_badge_v2.png"
3: 16
4: 28
6: 3
}
21 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_16.png~tplv-obj.png"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_16.png~tplv-obj.png"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_16.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_16.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&__live_platform__=webcast&type=popup&gravity=bottom&height=400&radius=8"
}
21 {
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_15.png"
6: 7
8 {
1: "\351\222\242\346\236\252\346\211\213"
2: "#FFFFFF"
3: 15
}
}
22 {
1: 45
2: 17
}
23 {
6: 16
19 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_16.png~tplv-obj.png"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_16.png~tplv-obj.png"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_16.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_16.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&__live_platform__=webcast&type=popup&gravity=bottom&height=400&radius=8"
}
}
24 {
1 {
1: "\351\222\242\346\236\252\346\211\213"
2: 15
3: 1
4 {
1 {
1: 2
2 {
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_15.png"
3: 48
4: 150
}
}
2: "\351\222\242\346\236\252\346\211\213"
}
}
}
32 {
2: 1
}
38: "0"
46: "MS4wLjABAAAALx1qtwLJiLVbuWXt7ZYTxHxVFvZz2PITy5YfQidfGp4"
50 {
1 {
3: 1008
4: 1125
}
3 {
3: 105
4: 111
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fnoble%2Fnoble_privilege_intro%2Findex.html%3Fforbid_right_back%3D1&status_bar_bg_color=%2300000000&noble_intercept=1&__live_platform__=webcast&type=fullscreen&hide_nav_bar=1&status_bar_color=white"
}
4: "\346\231\256\351\200\232\347\224\250\346\210\267"
6 {
3: 366
4: 615
}
7 {
3: 60
4: 108
}
8 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/noble_boarder.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/noble_boarder.png~tplv-obj.image"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/noble_boarder.png~tplv-obj.image"
2: "webcast/noble_boarder.png"
3: 64
4: 64
}
}
}
2: 1
}
}
4 {
1: 1
11: "\350\277\231\346\263\242\346\223\215\344\275\234\343\200\202\346\254\272\350\264\237\344\272\272\345\221\200"
}
}
}
2 {
1: 51510235218
3: "\351\222\242\346\236\252\345\205\204\345\274\237\350\266\205\345\223\245"
4: 1
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/2e8b032f45854441bd5e539ea892e00f~120x256.image"
}
21 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_admin_badge_v2.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_admin_badge_v2.png~tplv-obj.image"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_admin_badge_v2.png~tplv-obj.image"
2: "webcast/xigua_admin_badge_v2.png"
3: 16
4: 28
6: 3
}
21 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_16.png~tplv-obj.png"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_16.png~tplv-obj.png"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_16.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_16.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&__live_platform__=webcast&type=popup&gravity=bottom&height=400&radius=8"
}
21 {
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_15.png"
6: 7
8 {
1: "\351\222\242\346\236\252\346\211\213"
2: "#FFFFFF"
3: 15
}
}
22 {
1: 45
2: 17
}
23 {
6: 16
19 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_16.png~tplv-obj.png"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_16.png~tplv-obj.png"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_16.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_16.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&__live_platform__=webcast&type=popup&gravity=bottom&height=400&radius=8"
}
}
24 {
1 {
1: "\351\222\242\346\236\252\346\211\213"
2: 15
3: 1
4 {
1 {
1: 2
2 {
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_15.png"
3: 48
4: 150
}
}
2: "\351\222\242\346\236\252\346\211\213"
}
}
}
32 {
2: 1
}
38: "0"
46: "MS4wLjABAAAALx1qtwLJiLVbuWXt7ZYTxHxVFvZz2PITy5YfQidfGp4"
50 {
1 {
3: 1008
4: 1125
}
3 {
3: 105
4: 111
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fnoble%2Fnoble_privilege_intro%2Findex.html%3Fforbid_right_back%3D1&status_bar_bg_color=%2300000000&noble_intercept=1&__live_platform__=webcast&type=fullscreen&hide_nav_bar=1&status_bar_color=white"
}
4: "\346\231\256\351\200\232\347\224\250\346\210\267"
6 {
3: 366
4: 615
}
7 {
3: 60
4: 108
}
8 {
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/noble_boarder.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/noble_boarder.png~tplv-obj.image"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/noble_boarder.png~tplv-obj.image"
2: "webcast/noble_boarder.png"
3: 64
4: 64
}
}
}
3: "\350\277\231\346\263\242\346\223\215\344\275\234\343\200\202\346\254\272\350\264\237\344\272\272\345\221\200"
}
}
1 {
1: "WebcastChatMessage"
2 {
1 {
1: "WebcastChatMessage"
2: 6776883987831969295
3: 6776859660747344653
4: 1577866267933
6: 1
}
2 {
1: 100902326983
3: "\346\211\254\345\256\266\345\206\233\347\201\254\344\272\232\351\243\236"
4: 1
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/aade000f6df1961243c5~120x256.image"
}
21 {
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_9.png~tplv-obj.png"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_9.png~tplv-obj.png"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_9.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_9.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
21 {
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_4.png~tplv-obj.image"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_4.png~tplv-obj.image"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_4.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_4.png"
6: 7
8 {
1: "\351\222\242\346\236\252\346\211\213"
2: "#FFFFFF"
3: 4
}
}
22 {
1: 45
2: 7
}
23 {
6: 9
19 {
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_9.png~tplv-obj.png"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_9.png~tplv-obj.png"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_9.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_9.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
}
24 {
1 {
1: "\351\222\242\346\236\252\346\211\213"
2: 4
3: 1
4 {
1 {
1: 2
2 {
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_4.png~tplv-obj.image"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_4.png~tplv-obj.image"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_4.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_4.png"
3: 48
4: 150
}
}
2: "\351\222\242\346\236\252\346\211\213"
}
}
}
32: ""
38: "0"
46: "MS4wLjABAAAArfQQ4YVnKMKthzbKgv2swkggu8Ovv8eQCp56JmvvRvE"
50 {
1 {
3: 1008
4: 1125
}
3 {
3: 105
4: 111
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fnoble%2Fnoble_privilege_intro%2Findex.html%3Fforbid_right_back%3D1&type=fullscreen&hide_nav_bar=1&status_bar_color=white&status_bar_bg_color=%2300000000&noble_intercept=1&__live_platform__=webcast"
}
4: "\346\231\256\351\200\232\347\224\250\346\210\267"
6 {
3: 366
4: 615
}
7 {
3: 60
4: 108
}
8 {
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/noble_boarder.png~tplv-obj.image"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/noble_boarder.png~tplv-obj.image"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/noble_boarder.png~tplv-obj.image"
2: "webcast/noble_boarder.png"
3: 64
4: 64
}
}
}
3: "\351\230\277\344\274\237\345\220\271\347\211\233\346\257\224"
}
}
1 {
1: "WebcastRoomUserSeqMessage"
2 {
1 {
1: "WebcastRoomUserSeqMessage"
2: 6776884008732789507
3: 6776859660747344653
4: 1577866268029
}
2 {
1: 1975
2 {
1: 479033461313651
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/49b2bd0b157e4787917b029da02d2622~120x256.image"
}
23: ""
}
3: 1
}
2 {
1: 999
2 {
1: 3962278245043603
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/mosaic-legacy/241f1001013a2e8505175~120x256.image"
}
23: ""
}
3: 2
}
2 {
1: 571
2 {
1: 53231054839
9 {
1: "http://wx.qlogo.cn/mmopen/XFJ8HdGGwGDwy1reeaMqlfQrUh81uSv81HqUsESBK8YsNQ2oEIct3ibwdq1k55HLC7m43nfFiaX3EYpw2lKH4wibw/64"
}
23: ""
}
3: 3
}
2 {
1: 520
2 {
1: 88336033429
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/647c6fcddfa84d328d9c51f0294599d0~120x256.image"
}
23: ""
}
3: 4
}
2 {
1: 520
2 {
1: 58722717092
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/8a4dc6f002b545bca632615290f4527d~120x256.image"
}
23: ""
}
3: 5
}
2 {
1: 297
2 {
1: 52379408873
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/mosaic-legacy/24990023eae5e3325fcc~120x256.image"
}
23: ""
}
3: 6
}
2 {
1: 140
2 {
1: 57254508132
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/mosaic-legacy/216c00283d70176a9e97~120x256.image"
}
23: ""
}
3: 7
}
2 {
1: 128
2 {
1: 3056263838569380
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/fe8f000122d925f9a0fb~120x256.image"
}
23: ""
}
3: 8
}
2 {
1: 99
2 {
1: 23239313505
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/5d4700073713949f592e~120x256.image"
}
23: ""
}
3: 9
}
2 {
1: 35
2 {
1: 3239311302
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/737/6093229802~120x256.image"
}
23: ""
}
3: 10
}
2 {
1: 30
2 {
1: 822069738617544
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/2b5f6e3d331443b3bf51875567fa2b5d~120x256.image"
}
23: ""
}
3: 11
}
2 {
1: 22
2 {
1: 83166975758782
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/0baffeeb3d2d4fa8898b275968f18564~120x256.image"
}
23: ""
}
3: 12
}
2 {
1: 14
2 {
1: 104729678256
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/db140012b3f29800ab6d~120x256.image"
}
23: ""
}
3: 13
}
2 {
1: 11
2 {
1: 5538311676
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/mosaic-legacy/dad300141ece34b4e3c7~120x256.image"
}
23: ""
}
3: 14
}
2 {
1: 8
2 {
1: 109675723458
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/9cf549b429f740f6a90c41e4b5b632b9~120x256.image"
}
23: ""
}
3: 15
}
2 {
1: 6
2 {
1: 81425804261
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/9fd60005b91e43cc85e2~120x256.image"
}
23: ""
}
3: 16
}
2 {
1: 5
2 {
1: 2115111742610984
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/b20c086a5b644a6f919dfdd3dad442e6~120x256.image"
}
23: ""
}
3: 17
}
2 {
1: 3
2 {
1: 100743319316
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/6d8e7bba2195468fb24a4e3ea7992b92~120x256.image"
}
23: ""
}
3: 18
}
2 {
1: 2
2 {
1: 51035982268
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/d041e17415bc42c9a9815a8aaa2c3d8b~120x256.image"
}
23: ""
}
3: 19
}
2 {
1: 1
2 {
1: 1772009086784855
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/9fe0aa53dc254c0081a0fc2ce65f1559~120x256.image"
}
23: ""
}
3: 20
}
3: 826
4: "13\344\270\207\344\272\272\346\260\224"
6: 136763
}
}
2: "6776884008732789507_1577866268700_1_1"
3: 1000
4: 1577866268700
5: "fetch_time:1577866268700|start_time:1577866263586|fetch_id:6776884010443557636|flag:0|seq:22"

View File

@ -1,234 +0,0 @@
1 {
1: "WebcastRoomUserSeqMessage"
2 {
1 {
1: "WebcastRoomUserSeqMessage"
2: 6776963484661500684
3: 6776943780420389640
4: 1577884770601
}
2 {
1: 132
2 {
1: 3962279791967276
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/278ac6165ba34b7aa371e1df5ea337b3~120x256.image"
}
23: ""
}
3: 1
}
2 {
1: 66
2 {
1: 2933125236921479
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/2e1c9d64f34a4a3e8a326fe5394659fd~120x256.image"
}
23: ""
}
3: 2
}
2 {
1: 45
2 {
1: 50230797308
9 {
1: "http://p9-xg.bytecdn.cn/thumb/dac400045e7008dbd42d"
2: "dac400045e7008dbd42d"
}
23: ""
}
3: 3
}
2 {
1: 5
2 {
1: 9746464842
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/6ad34237256e4471b16810eb098224c0~120x256.image"
}
23: ""
}
3: 4
}
2 {
1: 5
2 {
1: 111552853752
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/mosaic-legacy/3792/5112637127~120x256.image"
}
23: ""
}
3: 5
}
2 {
1: 3
2 {
1: 16665341581
9 {
1: "http://p3-xg.bytecdn.cn/thumb/da80000309bef5b49fa0"
2: "da80000309bef5b49fa0"
}
23: ""
}
3: 6
}
2 {
2 {
1: 97942455882
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/mosaic-legacy/3792/5112637127~120x256.image"
}
23: ""
}
3: 7
}
2 {
2 {
1: 97363408846
9 {
1: "http://p3-xg.bytecdn.cn/thumb/dab00018fc4fda3b5a21"
2: "dab00018fc4fda3b5a21"
}
23: ""
}
3: 8
}
2 {
2 {
1: 96959753387
9 {
1: "http://p9-xg.bytecdn.cn/thumb/173b600285dcf9f649150"
2: "173b600285dcf9f649150"
}
23: ""
}
3: 9
}
2 {
2 {
1: 96119123780
9 {
1: "http://p9-xg.bytecdn.cn/thumb/241ef00000e3f17f517d7"
2: "241ef00000e3f17f517d7"
}
23: ""
}
3: 10
}
2 {
2 {
1: 9609510451
9 {
1: "http://p3-xg.bytecdn.cn/thumb/da51000807963daceae0"
2: "da51000807963daceae0"
}
23: ""
}
3: 11
}
2 {
2 {
1: 95931639233
9 {
1: "http://p9-xg.bytecdn.cn/thumb/71a30006cf20be61eb9b"
2: "71a30006cf20be61eb9b"
}
23: ""
}
3: 12
}
2 {
2 {
1: 94602295110
9 {
1: "http://p1-xg.bytecdn.cn/thumb/173b70008753becec983c"
2: "173b70008753becec983c"
}
23: ""
}
3: 13
}
2 {
2 {
1: 94432960458
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/3795/3047680722~120x256.image"
}
23: ""
}
3: 14
}
2 {
2 {
1: 94385438443
9 {
1: "http://p3-xg.bytecdn.cn/thumb/6593000eb2048e45ee0b"
2: "6593000eb2048e45ee0b"
}
23: ""
}
3: 15
}
2 {
2 {
1: 94193267099
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/mosaic-legacy/da57000b43a72cedd2fc~120x256.image"
}
23: ""
}
3: 16
}
2 {
2 {
1: 93948536567
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/fe7300005f28e10f3c52~120x256.image"
}
23: ""
}
3: 17
}
2 {
2 {
1: 93175525403
9 {
1: "http://p9-xg.bytecdn.cn/thumb/da83000d9328094b90d6"
2: "da83000d9328094b90d6"
}
23: ""
}
3: 18
}
2 {
2 {
1: 93064266997
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/6588002a7fcd121c60f6~120x256.image"
}
23: ""
}
3: 19
}
2 {
2 {
1: 92866340217
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3795/3044413937~120x256.image"
}
23: ""
}
3: 20
}
3: 365
4: "5.6\344\270\207\344\272\272\346\260\224"
6: 56661
}
}
2: "6776963484661500684_1577884771191_6776957423184169736_1"
3: 1000
4: 1577884771191
5: "fetch_time:1577884771191|start_time:1577884288940|fetch_id:6776963481247042317|flag:0|seq:1283"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,862 +0,0 @@
1 {
1: "WebcastMemberMessage"
2 {
1 {
1: "WebcastMemberMessage"
2: 6776965782439283463
3: 6776895930592398094
6: 1
8 {
1: "live_room_enter_toast"
2: "{0:user} \346\235\245\344\272\206{1:string}"
3 {
1: "#de000000"
4: 400
}
4 {
1: 11
2 {
1: "#61000000"
4: 400
}
21 {
1 {
1: 1587335753631549
3: "\345\260\217\345\244\251\346\211\215\350\264\235\345\243\263"
9 {
1: "http://p3.pstatp.com/thumb/3793/3131589739"
2: "3793/3131589739"
}
22 {
1: 33
2: 2
}
23 {
19: ""
}
24 {
1 {
4 {
1 {
1: 0
2: ""
}
}
}
}
32: ""
38: "0"
46: "MS4wLjABAAAAh0jOEAHZj6-a55dwsKu6i0ilHwHcWPx8mLImJ5iDJzfgkYhU0mFv-oLZ6yx6wNi0"
}
}
}
}
}
2 {
1: 1587335753631549
3: "\345\260\217\345\244\251\346\211\215\350\264\235\345\243\263"
9 {
1: "http://p3.pstatp.com/thumb/3793/3131589739"
2: "3793/3131589739"
}
22 {
1: 33
2: 2
}
23 {
19: ""
}
24 {
1 {
4 {
1 {
1: 0
2: ""
}
}
}
}
32: ""
38: "0"
46: "MS4wLjABAAAAh0jOEAHZj6-a55dwsKu6i0ilHwHcWPx8mLImJ5iDJzfgkYhU0mFv-oLZ6yx6wNi0"
}
3: 15103
10: 1
14: "132\344\270\207\344\272\272\346\260\224"
}
}
1 {
1: "WebcastMemberMessage"
2 {
1 {
1: "WebcastMemberMessage"
2: 6776965783190555404
3: 6776895930592398094
6: 1
8 {
1: "live_room_enter_toast"
2: "{0:user} \346\235\245\344\272\206{1:string}"
3 {
1: "#de000000"
4: 400
}
4 {
1: 11
2 {
1: "#61000000"
4: 400
}
21 {
1 {
1: 50909397248
3: "\347\214\223\347\214\223\347\214\223\345\255\220"
4: 1
9 {
1: "http://p1.pstatp.com/thumb/96b002412f02c3d2735"
2: "96b002412f02c3d2735"
}
21 {
1: "http://p3-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p6-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_5.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
22 {
1: 24
2: 1
}
23 {
6: 5
19 {
1: "http://p3-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p6-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_5.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
}
24 {
1 {
4 {
1 {
1: 0
2: ""
}
}
}
}
32: ""
38: "0"
46: "MS4wLjABAAAAwlVH0meNefJYE9l5cBWj5vZX8ooB9bII44Cf2CRXp9s"
}
}
}
}
}
2 {
1: 50909397248
3: "\347\214\223\347\214\223\347\214\223\345\255\220"
4: 1
9 {
1: "http://p1.pstatp.com/thumb/96b002412f02c3d2735"
2: "96b002412f02c3d2735"
}
21 {
1: "http://p3-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p6-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_5.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
22 {
1: 24
2: 1
}
23 {
6: 5
19 {
1: "http://p3-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p6-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_5.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_5.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
}
24 {
1 {
4 {
1 {
1: 0
2: ""
}
}
}
}
32: ""
38: "0"
46: "MS4wLjABAAAAwlVH0meNefJYE9l5cBWj5vZX8ooB9bII44Cf2CRXp9s"
}
3: 15103
10: 1
14: "132\344\270\207\344\272\272\346\260\224"
}
}
1 {
1: "WebcastRoomUserSeqMessage"
2 {
1 {
1: "WebcastRoomUserSeqMessage"
2: 6776965783814933256
3: 6776895930592398094
4: 1577885306057
}
2 {
1: 2997
2 {
1: 92747501043
2: 517409
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/mosaic-legacy/feaa00016eaa01bf172e~120x256.image"
}
23: ""
}
3: 1
}
2 {
1: 2198
2 {
1: 1182693581391939
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/dae10014972e8d70953e~120x256.image"
}
23: ""
}
3: 2
}
2 {
1: 1998
2 {
1: 5981054057
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/75660014ae3215bae055~120x256.image"
}
23: ""
}
3: 3
}
2 {
1: 1099
2 {
1: 3836408254
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/6620/5484795979~120x256.image"
}
23: ""
}
3: 4
}
2 {
1: 999
2 {
1: 830872766922279
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/5a67caf5ae404432aa0524c33001241c~120x256.image"
}
23: ""
}
3: 5
}
2 {
1: 999
2 {
1: 7185332641
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/754e3527d08540089a3adf6495845240~120x256.image"
}
23: ""
}
3: 6
}
2 {
1: 520
2 {
1: 93127918477
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/3795/3044413937~120x256.image"
}
23: ""
}
3: 7
}
2 {
1: 520
2 {
1: 50073154686
9 {
1: "http://p1-xg.bytecdn.cn/thumb/da790015e9c75441ff34"
2: "da790015e9c75441ff34"
}
23: ""
}
3: 8
}
2 {
1: 520
2 {
1: 104620584571
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/daa30018abcde9559b55~120x256.image"
}
23: ""
}
3: 9
}
2 {
1: 120
2 {
1: 5994520551
9 {
1: "http://p1-xg.bytecdn.cn/thumb/aae5000ffc17e4f1f5da"
2: "aae5000ffc17e4f1f5da"
}
23: ""
}
3: 10
}
2 {
1: 100
2 {
1: 54883854814
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/da68001693847d505008~120x256.image"
}
23: ""
}
3: 11
}
2 {
1: 99
2 {
1: 82020236564
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/5042000ff6673790f6d2~120x256.image"
}
23: ""
}
3: 12
}
2 {
1: 66
2 {
1: 3688188102
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/mosaic-legacy/e590005f1b8bdbd812c~120x256.image"
}
23: ""
}
3: 13
}
2 {
1: 38
2 {
1: 75972230499
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/173b400272ba1269fb7d8~120x256.image"
}
23: ""
}
3: 14
}
2 {
1: 20
2 {
1: 654947037492940
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/mosaic-legacy/2e549000299b4f464f99f~120x256.image"
}
23: ""
}
3: 15
}
2 {
1: 17
2 {
1: 6896749077
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/5046000873dbc5a8f31f~120x256.image"
}
23: ""
}
3: 16
}
2 {
1: 14
2 {
1: 50569473736
9 {
1: "http://p3-xg.bytecdn.cn/thumb/5d4b0002a7134afffa47"
2: "5d4b0002a7134afffa47"
}
23: ""
}
3: 17
}
2 {
1: 14
2 {
1: 2581241782866604
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/51c85ec9c5754938b89504217ae5bbbc~120x256.image"
}
23: ""
}
3: 18
}
2 {
1: 13
2 {
1: 50651928991
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/f81fee15e94a4405acc921916bfaff09~120x256.image"
}
23: ""
}
3: 19
}
2 {
1: 11
2 {
1: 106001804992
9 {
1: "http://sf6-ttcdn-tos.pstatp.com/img/mosaic-legacy/fe5f000080632ba520f5~120x256.image"
}
23: ""
}
3: 20
}
3: 15094
4: "132\344\270\207\344\272\272\346\260\224"
6: 1329944
}
}
1 {
1: "WebcastChatMessage"
2 {
1 {
1: "WebcastChatMessage"
2: 6776965784796482315
3: 6776895930592398094
4: 1577885306078
6: 1
}
2 {
1: 52120728008
3: "\346\234\250\345\255\2202910"
4: 1
9 {
1: "http://p1.pstatp.com/thumb/ef6000df19086df2853"
2: "ef6000df19086df2853"
}
21 {
1: "http://p3-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_3.png~tplv-obj.png"
1: "http://p6-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_3.png~tplv-obj.png"
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_3.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_3.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&__live_platform__=webcast&type=popup&gravity=bottom&height=400&radius=8"
}
22 {
1: 65
2: 16
}
23 {
6: 3
19 {
1: "http://p3-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_3.png~tplv-obj.png"
1: "http://p6-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_3.png~tplv-obj.png"
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/xigua_paygrade_level_3.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_3.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&__live_platform__=webcast&type=popup&gravity=bottom&height=400&radius=8"
}
}
24 {
1 {
4 {
1 {
1: 0
2: ""
}
}
}
}
32: ""
38: "0"
46: "MS4wLjABAAAAD4OSjJ5hRbYDzZI0GJT_usTlLPEBYFrtPEYzBwLiIzQ"
50 {
1 {
3: 1008
4: 1125
}
3 {
3: 105
4: 111
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fnoble%2Fnoble_privilege_intro%2Findex.html%3Fforbid_right_back%3D1&type=fullscreen&hide_nav_bar=1&status_bar_color=white&status_bar_bg_color=%2300000000&noble_intercept=1&__live_platform__=webcast"
}
4: "\346\231\256\351\200\232\347\224\250\346\210\267"
6 {
3: 366
4: 615
}
7 {
3: 60
4: 108
}
8 {
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/noble_boarder.png~tplv-obj.image"
1: "http://p3-webcast-ttcdn.byteimg.com/img/webcast/noble_boarder.png~tplv-obj.image"
1: "http://p9-webcast-ttcdn.byteimg.com/img/webcast/noble_boarder.png~tplv-obj.image"
2: "webcast/noble_boarder.png"
3: 64
4: 64
}
}
}
3: "\350\277\231\346\230\257\345\267\247\345\205\213\345\212\233\345\270\275\345\255\220\357\274\237"
}
}
1 {
1: "WebcastMemberMessage"
2 {
1 {
1: "WebcastMemberMessage"
2: 6776965784520887054
3: 6776895930592398094
6: 1
8 {
1: "live_room_enter_toast"
2: "{0:user} \346\235\245\344\272\206{1:string}"
3 {
1: "#de000000"
4: 400
}
4 {
1: 11
2 {
1: "#61000000"
4: 400
}
21 {
1 {
1: 71581494772
3: "\345\217\253\346\210\221\350\221\211\345\220\214\345\255\246"
4: 1
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/mosaic-legacy/3792/5112637127~120x256.image"
}
22 {
1: 6
}
23 {
19: ""
}
24 {
1 {
4 {
1 {
1: 0
2: ""
}
}
}
}
32: ""
38: "0"
46: "MS4wLjABAAAAfgxQATVlN1REs0ezLccSYBNp34sVcfh3EZHMu5Fi8uE"
}
}
}
}
}
2 {
1: 71581494772
3: "\345\217\253\346\210\221\350\221\211\345\220\214\345\255\246"
4: 1
9 {
1: "http://sf3-ttcdn-tos.pstatp.com/img/mosaic-legacy/3792/5112637127~120x256.image"
}
22 {
1: 6
}
23 {
19: ""
}
24 {
1 {
4 {
1 {
1: 0
2: ""
}
}
}
}
32: ""
38: "0"
46: "MS4wLjABAAAAfgxQATVlN1REs0ezLccSYBNp34sVcfh3EZHMu5Fi8uE"
}
3: 15103
10: 1
14: "132\344\270\207\344\272\272\346\260\224"
}
}
1 {
1: "WebcastMemberMessage"
2 {
1 {
1: "WebcastMemberMessage"
2: 6776965785094048520
3: 6776895930592398094
6: 1
8 {
1: "live_room_enter_toast"
2: "{0:user} \346\235\245\344\272\206{1:string}"
3 {
1: "#de000000"
4: 400
}
4 {
1: 11
2 {
1: "#61000000"
4: 400
}
21 {
1 {
1: 6205145196
3: "\346\210\221\344\270\215\346\230\257\350\200\201\351\211\204"
4: 1
9 {
1: "http://p1-xg.bytecdn.cn/thumb/249a001395445a62671d"
2: "249a001395445a62671d"
}
21 {
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_8.png~tplv-obj.png"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_8.png~tplv-obj.png"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_8.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_8.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
21 {
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_14.png"
6: 7
8 {
1: "\345\270\203\344\270\200\347\217\255"
2: "#FFFFFF"
3: 14
}
}
22 {
1: 15
2: 54
}
23 {
6: 8
19 {
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_8.png~tplv-obj.png"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_8.png~tplv-obj.png"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_8.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_8.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
}
24 {
1 {
1: "\345\270\203\344\270\200\347\217\255"
2: 14
3: 1
4 {
1 {
1: 2
2 {
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_14.png"
3: 48
4: 150
}
}
2: "\345\270\203\344\270\200\347\217\255"
}
}
}
32: ""
38: "0"
46: "MS4wLjABAAAAGMn5pO7qE_ZZu6ETuJmfSW8KLhLOtRkLnr3IiLE2e6A"
}
}
}
}
}
2 {
1: 6205145196
3: "\346\210\221\344\270\215\346\230\257\350\200\201\351\211\204"
4: 1
9 {
1: "http://p1-xg.bytecdn.cn/thumb/249a001395445a62671d"
2: "249a001395445a62671d"
}
21 {
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_8.png~tplv-obj.png"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_8.png~tplv-obj.png"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_8.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_8.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
21 {
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_14.png"
6: 7
8 {
1: "\345\270\203\344\270\200\347\217\255"
2: "#FFFFFF"
3: 14
}
}
22 {
1: 15
2: 54
}
23 {
6: 8
19 {
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_8.png~tplv-obj.png"
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_8.png~tplv-obj.png"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/xigua_paygrade_level_8.png~tplv-obj.png"
2: "webcast/xigua_paygrade_level_8.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2FhonorLevel%2Findex.html&type=popup&gravity=bottom&height=400&radius=8&__live_platform__=webcast"
}
}
24 {
1 {
1: "\345\270\203\344\270\200\347\217\255"
2: 14
3: 1
4 {
1 {
1: 2
2 {
1: "http://p9-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
1: "http://p6-webcast-xgcdn.byteimg.com/img/webcast/xigua_fansclub_medal_14.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_14.png"
3: 48
4: 150
}
}
2: "\345\270\203\344\270\200\347\217\255"
}
}
}
32: ""
38: "0"
46: "MS4wLjABAAAAGMn5pO7qE_ZZu6ETuJmfSW8KLhLOtRkLnr3IiLE2e6A"
}
3: 15103
10: 1
14: "132\344\270\207\344\272\272\346\260\224"
}
}
1 {
1: "WebcastFansclubStatisticsMessage"
2 {
1 {
1: "WebcastFansclubStatisticsMessage"
2: 6776950071441869579
3: 6776895930592398094
4: 1577885306430
6: 1
}
2: "\345\270\203\344\270\200\347\217\255"
3: 19325
}
}
1 {
1: "WebcastFansclubMessage"
2 {
1 {
1: "WebcastFansclubMessage"
2: 6776950071441885963
3: 6776895930592398094
4: 1577885306441
6: 1
}
2: 2
3: "\346\201\255\345\226\234 \347\210\261\345\220\203\351\261\274\347\232\204\347\213\256\345\255\220\351\270\255 \346\210\220\344\270\272\347\254\25419325\345\220\215\347\262\211\344\270\235\345\233\242\346\210\220\345\221\230"
4 {
1: 109556646111
3: "\347\210\261\345\220\203\351\261\274\347\232\204\347\213\256\345\255\220\351\270\255"
9 {
1: "http://sf1-ttcdn-tos.pstatp.com/img/tos-cn-i-0022/66d462f176c841a0a4939ad355fe8c00~120x256.image"
}
24 {
1 {
1: "\345\270\203\344\270\200\347\217\255"
2: 1
3: 1
4 {
1 {
1: 2
2 {
1: "https://p1.pstatp.com/obj/webcast/xigua_fansclub_1.png"
2: "webcast/xigua_fansclub_1.png"
3: 48
4: 150
}
}
2: "\345\270\203\344\270\200\347\217\255"
}
}
}
}
}
}
2: "6776950071441885963_1577885306619_6776965731513060100_1"
3: 1000
4: 1577885306619
5: "fetch_time:1577885306619|start_time:1577885302380|fetch_id:6776965761064883715|flag:0|seq:387"

File diff suppressed because it is too large Load Diff

View File

@ -1,256 +0,0 @@
1 {
1: "WebcastChatMessage"
2 {
1 {
1: "WebcastChatMessage"
2: 6902669212519992068
3: 6902629276546566925
6: 1
8 {
1: "webcast_chat_display_text"
2: "{0:user}{1:string}"
3 {
1: "#ff36c0cf"
4: 400
}
4 {
1: 11
2 {
1: "#60000000"
4: 400
}
21 {
1 {
1: 5518138898
3: "\345\247\232\345\247\232\347\220\263\347\232\2042\345\247\220\345\244\253"
4: 1
9 {
1: "https://p1-dy.bytexservice.com/img/user-avatar/deb96a5e7e07f60a613531670a570736~300x300.image"
}
21 {
1: "http://p9-webcast-ttcdn.byteimg.com/img/webcast/xigua_admin_badge_v2.png~tplv-obj.image"
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/xigua_admin_badge_v2.png~tplv-obj.image"
2: "webcast/xigua_admin_badge_v2.png"
3: 16
4: 28
6: 3
}
21 {
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/25_xigua_honor_level.png~tplv-obj.png"
1: "http://p9-webcast-ttcdn.byteimg.com/img/webcast/25_xigua_honor_level.png~tplv-obj.png"
2: "webcast/25_xigua_honor_level.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fhonor_level%2Fuser%2Findex.html&hide_nav_bar=1&hide_status_bar=0&__live_platform__=webcast&type=fullscreen"
}
21 {
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
1: "http://p6-webcast-ttcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_15.png"
6: 7
8 {
1: "\345\247\232\345\247\232\347\220\263"
2: "#FFFFFF"
3: 15
}
}
22 {
1: 13
2: 86
3: 2
}
23 {
6: 25
19 {
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/25_xigua_honor_level.png~tplv-obj.png"
1: "http://p9-webcast-ttcdn.byteimg.com/img/webcast/25_xigua_honor_level.png~tplv-obj.png"
2: "webcast/25_xigua_honor_level.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fhonor_level%2Fuser%2Findex.html&hide_nav_bar=1&hide_status_bar=0&__live_platform__=webcast&type=fullscreen"
}
}
24 {
1 {
1: "\345\247\232\345\247\232\347\220\263"
2: 15
3: 1
4 {
1: "\010\002\022\342\001\nZhttp://p1-webcast-ttcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image\nZhttp://p6-webcast-ttcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image\022#webcast/xigua_fansclub_medal_15.png\0300 \226\001"
2: "\345\247\232\345\247\232\347\220\263"
}
6: 61788610240
}
}
32 {
2: 1
}
38: "0"
46: "MS4wLjABAAAAKkWCgUKAN3GtNdQ0jqr8zAt3KtIc9kAc1GaJ32VcH3E"
54: 3
61 {
1: "http://p9-webcast-ttcdn.byteimg.com/img/webcast/xigua_admin_badge_v2.png~tplv-obj.image"
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/xigua_admin_badge_v2.png~tplv-obj.image"
2: "webcast/xigua_admin_badge_v2.png"
3: 16
4: 28
6: 3
}
61 {
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/25_xigua_honor_level.png~tplv-obj.png"
1: "http://p9-webcast-ttcdn.byteimg.com/img/webcast/25_xigua_honor_level.png~tplv-obj.png"
2: "webcast/25_xigua_honor_level.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fhonor_level%2Fuser%2Findex.html&hide_nav_bar=1&hide_status_bar=0&__live_platform__=webcast&type=fullscreen"
}
61 {
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
1: "http://p6-webcast-ttcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_15.png"
6: 7
8 {
1: "\345\247\232\345\247\232\347\220\263"
2: "#FFFFFF"
3: 15
}
}
}
2: 1
}
}
4 {
1: 1
11: "@\345\247\232\345\256\266\344\272\214\345\247\221\345\207\211 \346\210\221\345\211\215\345\244\251\346\235\245\346\267\261\345\234\263\344\272\206"
}
}
11: 31003
}
2 {
1: 5518138898
3: "\345\247\232\345\247\232\347\220\263\347\232\2042\345\247\220\345\244\253"
4: 1
9 {
1: "https://p1-dy.bytexservice.com/img/user-avatar/deb96a5e7e07f60a613531670a570736~300x300.image"
}
21 {
1: "http://p9-webcast-ttcdn.byteimg.com/img/webcast/xigua_admin_badge_v2.png~tplv-obj.image"
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/xigua_admin_badge_v2.png~tplv-obj.image"
2: "webcast/xigua_admin_badge_v2.png"
3: 16
4: 28
6: 3
}
21 {
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/25_xigua_honor_level.png~tplv-obj.png"
1: "http://p9-webcast-ttcdn.byteimg.com/img/webcast/25_xigua_honor_level.png~tplv-obj.png"
2: "webcast/25_xigua_honor_level.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fhonor_level%2Fuser%2Findex.html&hide_nav_bar=1&hide_status_bar=0&__live_platform__=webcast&type=fullscreen"
}
21 {
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
1: "http://p6-webcast-ttcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_15.png"
6: 7
8 {
1: "\345\247\232\345\247\232\347\220\263"
2: "#FFFFFF"
3: 15
}
}
22 {
1: 13
2: 86
3: 2
}
23 {
6: 25
19 {
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/25_xigua_honor_level.png~tplv-obj.png"
1: "http://p9-webcast-ttcdn.byteimg.com/img/webcast/25_xigua_honor_level.png~tplv-obj.png"
2: "webcast/25_xigua_honor_level.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fhonor_level%2Fuser%2Findex.html&hide_nav_bar=1&hide_status_bar=0&__live_platform__=webcast&type=fullscreen"
}
}
24 {
1 {
1: "\345\247\232\345\247\232\347\220\263"
2: 15
3: 1
4 {
1 {
1: 2
2 {
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
1: "http://p6-webcast-ttcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_15.png"
3: 48
4: 150
}
}
2: "\345\247\232\345\247\232\347\220\263"
}
6: 61788610240
}
}
32 {
2: 1
}
38: "0"
46: "MS4wLjABAAAAKkWCgUKAN3GtNdQ0jqr8zAt3KtIc9kAc1GaJ32VcH3E"
54: 3
61 {
1: "http://p9-webcast-ttcdn.byteimg.com/img/webcast/xigua_admin_badge_v2.png~tplv-obj.image"
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/xigua_admin_badge_v2.png~tplv-obj.image"
2: "webcast/xigua_admin_badge_v2.png"
3: 16
4: 28
6: 3
}
61 {
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/25_xigua_honor_level.png~tplv-obj.png"
1: "http://p9-webcast-ttcdn.byteimg.com/img/webcast/25_xigua_honor_level.png~tplv-obj.png"
2: "webcast/25_xigua_honor_level.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fhonor_level%2Fuser%2Findex.html&hide_nav_bar=1&hide_status_bar=0&__live_platform__=webcast&type=fullscreen"
}
61 {
1: "http://p1-webcast-ttcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
1: "http://p6-webcast-ttcdn.byteimg.com/img/webcast/xigua_fansclub_medal_15.png~tplv-obj.image"
2: "webcast/xigua_fansclub_medal_15.png"
6: 7
8 {
1: "\345\247\232\345\247\232\347\220\263"
2: "#FFFFFF"
3: 15
}
}
}
3: "@\345\247\232\345\256\266\344\272\214\345\247\221\345\207\211 \346\210\221\345\211\215\345\244\251\346\235\245\346\267\261\345\234\263\344\272\206"
9 {
1 {
1: "http://p3-webcast-ttcdn.byteimg.com/img/webcast/userlabel_regular_chat.png~tplv-obj.image"
1: "http://p6-webcast-ttcdn.byteimg.com/img/webcast/userlabel_regular_chat.png~tplv-obj.image"
2: "webcast/userlabel_regular_chat.png"
5: "#E0BCD4"
}
2: 11
}
}
3: 6902669212519992068
}
2: "1607153101490_6902670004165030044_6902669995575083008_1"
3: 1000
4: 1607153101490
5: "fetch_time:1607153101490|start_time:0|fetch_id:6902670004165030042|flag:0|seq:2080|next_cursor:1607153101490_6902670004165030044_6902669995575083008_1"

View File

@ -1,364 +0,0 @@
1 {
1: "WebcastControlMessage"
2 {
1 {
1: "WebcastControlMessage"
2: 6902672961476774663
3: 6902629276546566925
4: 1607153789195
6: 1
}
2: 3
}
3: 6902672961476774663
}
1 {
1: "WebcastMemberMessage"
2 {
1 {
1: "WebcastMemberMessage"
2: 6902672961728662285
3: 6902629276546566925
6: 1
8 {
1: "live_room_enter_toast"
2: "{0:user} \346\235\245\344\272\206{1:string}"
3 {
1: "#de000000"
4: 400
}
4 {
1: 11
2 {
1: "#61000000"
4: 400
}
21 {
1 {
1: 2638466963214383
2: 1520817
3: "\350\213\261\345\256\207girl"
9 {
1: "https://sf3-ttcdn-tos.pstatp.com/img/user-avatar/a15266741ef770c810e18e5e6d073da9~300x300.image"
}
21 {
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
2: "webcast/3_xigua_honor_level.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fhonor_level%2Fuser%2Findex.html&type=fullscreen&hide_nav_bar=1&hide_status_bar=0&__live_platform__=webcast"
}
22 {
1: 60
2: 120
}
23 {
6: 3
19 {
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
2: "webcast/3_xigua_honor_level.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fhonor_level%2Fuser%2Findex.html&type=fullscreen&hide_nav_bar=1&hide_status_bar=0&__live_platform__=webcast"
}
}
24 {
1 {
4 {
1: "\010\000\022\000"
}
}
}
32: ""
38: "1520817"
46: "MS4wLjABAAAATNQnQSVI6ePiovK48LHJHvefLO_4RAmla1Hkn0GYTWc8oE5u0a0VZnmPM3VKnaSh"
54: 3
61 {
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
2: "webcast/3_xigua_honor_level.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fhonor_level%2Fuser%2Findex.html&type=fullscreen&hide_nav_bar=1&hide_status_bar=0&__live_platform__=webcast"
}
}
}
}
}
9: 1
10: 1
11: 42000
}
2 {
1: 2638466963214383
2: 1520817
3: "\350\213\261\345\256\207girl"
9 {
1: "https://sf3-ttcdn-tos.pstatp.com/img/user-avatar/a15266741ef770c810e18e5e6d073da9~300x300.image"
}
21 {
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
2: "webcast/3_xigua_honor_level.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fhonor_level%2Fuser%2Findex.html&type=fullscreen&hide_nav_bar=1&hide_status_bar=0&__live_platform__=webcast"
}
22 {
1: 60
2: 120
}
23 {
6: 3
19 {
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
2: "webcast/3_xigua_honor_level.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fhonor_level%2Fuser%2Findex.html&type=fullscreen&hide_nav_bar=1&hide_status_bar=0&__live_platform__=webcast"
}
}
24 {
1 {
4 {
1 {
1: 0
2: ""
}
}
}
}
32: ""
38: "1520817"
46: "MS4wLjABAAAATNQnQSVI6ePiovK48LHJHvefLO_4RAmla1Hkn0GYTWc8oE5u0a0VZnmPM3VKnaSh"
54: 3
61 {
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
2: "webcast/3_xigua_honor_level.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fhonor_level%2Fuser%2Findex.html&type=fullscreen&hide_nav_bar=1&hide_status_bar=0&__live_platform__=webcast"
}
}
3: 31
10: 1
14: "0\344\272\272"
18 {
1: "live_room_enter_toast"
2: "{0:user} \346\235\245\344\272\206{1:string}"
3 {
1: "#de000000"
4: 400
}
4 {
1: 11
2 {
1: "#61000000"
4: 400
}
21 {
1 {
1: 2638466963214383
2: 1520817
3: "\350\213\261\345\256\207girl"
9 {
1: "https://sf3-ttcdn-tos.pstatp.com/img/user-avatar/a15266741ef770c810e18e5e6d073da9~300x300.image"
}
21 {
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
2: "webcast/3_xigua_honor_level.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fhonor_level%2Fuser%2Findex.html&type=fullscreen&hide_nav_bar=1&hide_status_bar=0&__live_platform__=webcast"
}
22 {
1: 60
2: 120
}
23 {
6: 3
19 {
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
2: "webcast/3_xigua_honor_level.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fhonor_level%2Fuser%2Findex.html&type=fullscreen&hide_nav_bar=1&hide_status_bar=0&__live_platform__=webcast"
}
}
24 {
1 {
4 {
1 {
1: 0
2: ""
}
}
}
}
32: ""
38: "1520817"
46: "MS4wLjABAAAATNQnQSVI6ePiovK48LHJHvefLO_4RAmla1Hkn0GYTWc8oE5u0a0VZnmPM3VKnaSh"
54: 3
61 {
1: "http://p1-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
1: "http://p3-webcast-xgcdn.byteimg.com/img/webcast/3_xigua_honor_level.png~tplv-obj.png"
2: "webcast/3_xigua_honor_level.png"
3: 16
4: 30
6: 1
7: "sslocal://webcast_webview?url=https%3A%2F%2Fwebcast.ixigua.com%2Ffalcon%2Fwebcast_xigua%2Fpage%2Fhonor_level%2Fuser%2Findex.html&type=fullscreen&hide_nav_bar=1&hide_status_bar=0&__live_platform__=webcast"
}
}
}
}
}
}
3: 6902672961728662285
}
1 {
1: "WebcastMemberMessage"
2 {
1 {
1: "WebcastMemberMessage"
2: 6902672961866681091
3: 6902629276546566925
6: 1
8 {
1: "live_room_enter_toast"
2: "{0:user} \346\235\245\344\272\206{1:string}"
3 {
1: "#de000000"
4: 400
}
4 {
1: 11
2 {
1: "#61000000"
4: 400
}
21 {
1 {
1: 1015537608169303
3: "\347\224\250\346\210\267525366763846"
9 {
1: "https://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
22 {
1: 31
}
23 {
19: ""
}
24 {
1 {
4 {
1: "\010\000\022\000"
}
}
}
32: ""
38: "0"
46: "MS4wLjABAAAAXDp4yUHFF_sA3Uf9T4OPkW0dk-9SUYxbFNFrs7CcyhAcjYzdsYFYE5vuUdaHbo9R"
54: 3
}
}
}
}
9: 1
10: 1
11: 42000
}
2 {
1: 1015537608169303
3: "\347\224\250\346\210\267525366763846"
9 {
1: "https://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
22 {
1: 31
}
23 {
19: ""
}
24 {
1 {
4 {
1 {
1: 0
2: ""
}
}
}
}
32: ""
38: "0"
46: "MS4wLjABAAAAXDp4yUHFF_sA3Uf9T4OPkW0dk-9SUYxbFNFrs7CcyhAcjYzdsYFYE5vuUdaHbo9R"
54: 3
}
10: 1
14: "0\344\272\272"
18 {
1: "live_room_enter_toast"
2: "{0:user} \346\235\245\344\272\206{1:string}"
3 {
1: "#de000000"
4: 400
}
4 {
1: 11
2 {
1: "#61000000"
4: 400
}
21 {
1 {
1: 1015537608169303
3: "\347\224\250\346\210\267525366763846"
9 {
1: "https://sf1-ttcdn-tos.pstatp.com/img/mosaic-legacy/3791/5070639578~120x256.image"
}
22 {
1: 31
}
23 {
19: ""
}
24 {
1 {
4 {
1 {
1: 0
2: ""
}
}
}
}
32: ""
38: "0"
46: "MS4wLjABAAAAXDp4yUHFF_sA3Uf9T4OPkW0dk-9SUYxbFNFrs7CcyhAcjYzdsYFYE5vuUdaHbo9R"
54: 3
}
}
}
}
}
3: 6902672961866681091
}
2: "1607153789923_6902672963397497753_6902669995575083008_1"
3: 1000
4: 1607153789923
5: "fetch_time:1607153789923|start_time:0|fetch_id:6902672959102530453|flag:0|seq:2684|next_cursor:1607153789923_6902672963397497753_6902669995575083008_1"

48
Gift.py Normal file
View File

@ -0,0 +1,48 @@
import requests
from User import User
class Gift:
ID:int = 0
count:int = 0
roomID:int = 0
giftList:dict = {10001: {"Name": "西瓜", "Price": 0}}
amount:int = 0
user:User = None
def __init__(self, json=None):
if json:
self.parse(json)
def parse(self, json):
self.user = User(json)
if "Msg" in json:
if "present_end_info" in json["Msg"]:
self.ID = json["Msg"]['present_end_info']['id']
self.count = json["Msg"]['present_end_info']['count']
elif "present_info" in json["Msg"]:
self.ID = json["Msg"]['present_info']['id']
self.count = json["Msg"]['present_info']['repeat_count']
if self.ID in self.giftList:
self.amount = self.giftList[self.ID]["Price"] * self.count
@staticmethod
def update(roomID):
Gift.roomID = roomID
p = requests.get("https://live.ixigua.com/api/gifts/{roomID}".format(roomID= roomID))
d = p.json()
if isinstance(d, int) or "data" not in d:
print("错误:礼物更新失败")
else:
for i in d["data"]:
Gift.giftList[i["ID"]] = {"Name": i["Name"], "Price": i["DiamondCount"]}
def __str__(self):
if self.ID in self.giftList:
giftN = self.giftList[self.ID]["Name"]
else:
giftN = "未知礼物[{}]".format(self.ID)
return "{user} 送出的 {count}{name}".format(user= self.user, count= self.count, name= giftN)
def __unicode__(self):
return self.__str__()

13
LICENSE
View File

@ -1,13 +0,0 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

View File

@ -1,31 +0,0 @@
# XiguaLiveDanmakuHelper
## 现在西瓜视频搜索接口无法使用建议开发者自己找到自己的用户ID写死加载即可
### 因西瓜直播弹幕接口换成了ProtoBuf已经尝试解析出了部分proto
### 从安卓9.4版本后 *(大概是)* 发现需要连接Websocket才能获取弹幕且又是魔改protobuf搞不懂手动断开Websocket后才会轮询请求
### ~~西瓜直播弹幕助手--界面版~~
> 界面版:[q792602257/XiguaDanmakuHelperGUI](https://github.com/q792602257/XiguaDanmakuHelperGUI "C# ver")
> #### 该项目已经荒废,除非你知道如何开发,否则不建议使用
### 西瓜直播弹幕接口```api.py```
> - 基于安卓9.6.6(96615)
### 西瓜直播弹幕助手--礼物端```WinMain.py```
### 西瓜直播弹幕助手--录播端```WebMain.py```
> - 能够自动进行ffmpeg转码
> - 转码后自动上传至B站
> - 顺便还能自己清理录播的文件移动到一个位置执行shell命令上传百度云
> - 把录像文件分一定大小保存B站有限制但是不知道是多少
> - 少部分错误包容机制
> - 有一个简单的WEB页面及简单的控制接口
### ~~计划更新~~
### 随缘更新

View File

@ -1,40 +0,0 @@
from .User import User
from .Lottery import Lottery
from XiguaMessage_pb2 import ChatMessage
class Chat:
content = ""
user = None
filterString = ["", ]
isFiltered = False
def __init__(self, json=None, lottery: Lottery = None):
if lottery:
self.filterString.append(lottery.content)
if json:
if type(json) == bytes:
self.parsePb(json)
else:
self.parse(json)
def parsePb(self, raw):
_message = ChatMessage()
_message.ParseFromString(raw)
self.user = User(_message.user)
self.content = _message.content
if self.content in self.filterString:
self.isFiltered = True
def parse(self, json):
self.user = User(json)
if "extra" in json:
if "content" in json["extra"]:
self.content = json["extra"]['content']
if self.content in self.filterString:
self.isFiltered = True
def __str__(self):
return "{} : {}".format(self.user, self.content)
def __unicode__(self):
return self.__str__()

View File

View File

@ -1,73 +0,0 @@
import requests
from .User import User
from XiguaMessage_pb2 import GiftMessage
class Gift:
giftList = {}
def __init__(self, json=None):
self.ID = 0
self.count = 0
self.user = None
self.isFinished = False
self.backupName = None
if json:
if type(json) == bytes:
self.parsePb(json)
else:
self.parse(json)
def parsePb(self, raw):
_message = GiftMessage()
_message.ParseFromString(raw)
self.user = User(_message.user)
self.ID = _message.giftId
self.count = _message.repeated
self.isFinished = _message.isFinished
self.backupName = _message.commonInfo.displayText.params.gifts.gift.name
def parse(self, json):
self.user = User(json)
if "extra" in json and json["extra"] is not None:
if "present_info" in json["extra"] and json["extra"]['present_info'] is not None:
self.ID = int(json["extra"]['present_info']['id'])
self.count = json["extra"]['present_info']['repeat_count']
elif "present_end_info" in json["extra"] and json["extra"]['present_end_info'] is not None:
self.ID = int(json["extra"]['present_end_info']['id'])
self.count = json["extra"]['present_end_info']['count']
def isAnimate(self):
if self.ID != 0 and self.ID in self.giftList:
if 'combo' in self.giftList[self.ID]:
return self.giftList[self.ID]["combo"] == False
elif 'meta' in self.giftList[self.ID] and 'combo' in self.giftList[self.ID]['meta']:
return self.giftList[self.ID]['meta']["combo"] == False
elif 'type' in self.giftList[self.ID]:
return self.giftList[self.ID]["type"] == 2
return False
@property
def name(self):
if self.ID in self.giftList:
return self.giftList[self.ID]["name"]
elif self.backupName is not None:
return self.backupName
else:
return "未知礼物[{}]".format(self.ID)
def __str__(self):
return "{user} 送出的 {count}{name}".format(user=self.user, count=self.count, name=self.name)
def __unicode__(self):
return self.__str__()
def __repr__(self):
return "西瓜礼物【{}(ID:{})】".format(self.name, self.ID)
@classmethod
def addGift(cls, _gift):
if 'id' not in _gift:
return
_id = int(_gift["id"])
cls.giftList[_id] = _gift

View File

@ -1,71 +0,0 @@
# coding=utf-8
import requests
import time
from .LuckyUser import LuckyUser
class Lottery:
ID = 0
isActive = False
content = ""
isFinished = False
luckyUsers = []
joinedUserCount = 0
prizeName = ""
finish = 0
def __init__(self, json=None):
if json:
self.parse(json)
def parse(self, json):
if "lottery_info" in json and json["lottery_info"] is not None:
self.isActive = int(json["lottery_info"]["status"]) > 0
self.ID = json["lottery_info"]["lottery_id"]
for i in json["lottery_info"]['conditions']:
if i['type'] != 3:
continue
self.content = i["content"]
self.joinedUserCount = int(json["lottery_info"]["candidate_num"])
self.prizeName = json["lottery_info"]["prize_info"]["name"]
_delta = int(json["lottery_info"]["draw_time"]) - int(json["lottery_info"]["current_time"])
self.finish = time.time()+_delta+1
elif "extra" in json and json["extra"] is not None:
if "lottery_info" in json["extra"] and json["extra"]["lottery_info"] is not None:
return self.parse(json["extra"])
def update(self):
if self.isActive:
if not self.isFinished and self.finish > time.time():
self.checkFinished()
return True
return False
def checkFinished(self):
p = requests.get("https://i.snssdk.com/videolive/lottery/check_user_right?lottery_id={}"
"&version_code=730&device_platform=android".format(
self.ID
))
d = p.json()
if d["base_resp"]["status_code"] != 0:
self.isActive = False
self.isFinished = False
return
self.isActive = int(d["lottery_info"]["status"]) > 0
self.isFinished = int(d["lottery_info"]["status"]) == 2
self.joinedUserCount = int(d["lottery_info"]["candidate_num"])
if self.isFinished:
self.luckyUsers = [ LuckyUser(i) for i in d["lottery_info"]["lucky_users"] ]
def __str__(self):
if self.isFinished:
ret = "恭喜以下中奖用户:\n"
for i in self.luckyUsers:
ret += "> {} {}\n".format(i,self.prizeName)
ret += "> 参与人数:{}".format(self.joinedUserCount)
return ret
elif self.isActive:
return "正在抽奖中。。。\n" \
"> 参与人数:{}".format(self.joinedUserCount)
else:
return "抽奖已失效"

View File

@ -1,19 +0,0 @@
from .User import User
class LuckyUser:
user = None
count = 0
def __init__(self, json=None):
if json:
self.parse(json)
def parse(self, json):
self.user = User()
self.user.ID = json['user_id']
self.user.name = json['user_name']
self.count = int(json["grant_count"])
def __str__(self):
return "用户 {} 获得了 {}".format(self.user,self.count)

View File

@ -1,36 +0,0 @@
from .User import User
class MemberMsg:
type = 0
content = ""
user = None
def __init__(self, json=None):
if json:
self.parse(json)
def parse(self, json):
self.user = User(json)
if "extra" in json:
if "action" in json["extra"]:
self.type = json["extra"]['action']
elif "content" in json["extra"]:
self.content = json["extra"]['content']
def __str__(self):
if self.type == 3:
return "{} 被禁言了".format(self.user)
elif self.type == 4:
return "{} 被取消禁言了".format(self.user)
elif self.type == 5:
return "{} 被任命为房管".format(self.user)
elif self.type == 1:
return "{} 进入了房间".format(self.user)
else:
if self.content == "":
return "未知消息{} 关于用户 {}".format(self.type, self.user)
return self.content.format(self.user)
def __unicode__(self):
return self.__str__()

View File

@ -1,77 +0,0 @@
from XiguaUser_pb2 import User as UserPb
class User:
def __init__(self, json=None):
self.ID = 0
self.name = ""
self.brand = ""
self.level = 0
self.type = 0
self.block = False
self.mute = False
if json:
if type(json) == bytes:
self.parsePb(json)
elif type(json) == UserPb:
self.parseUserPb(json)
else:
self.parse(json)
def parseUserPb(self, _user):
self.ID = _user.id
self.name = _user.nickname
self.brand = _user.fansClub.fansClub.title
self.level = _user.fansClub.fansClub.level
def parsePb(self, raw):
_user = UserPb()
_user.ParseFromString(raw)
self.parseUserPb(_user)
def parse(self, json):
if "extra" in json:
if "user" in json["extra"] and json["extra"]["user"] is not None:
self.ID = json["extra"]['user']['user_id']
self.name = json["extra"]['user']['name']
if "im_discipulus_info" in json["extra"] and json["extra"]["im_discipulus_info"] is not None:
self.level = json["extra"]["im_discipulus_info"]["level"]
self.brand = json["extra"]["im_discipulus_info"]["discipulus_group_title"]
if "user_room_auth_status" in json["extra"] and json["extra"]["user_room_auth_status"] is not None:
self.type = json["extra"]["user_room_auth_status"]["user_type"]
self.block = json["extra"]["user_room_auth_status"]["is_block"]
self.mute = json["extra"]["user_room_auth_status"]["is_silence"]
if "user_info" in json and json["user_info"] is not None:
self.ID = json['user_info']['user_id']
self.name = json['user_info']['name']
if "anchor" in json and json["anchor"] is not None:
if "user_info" in json["anchor"] and json["anchor"]['user_info'] is not None:
self.ID = json["anchor"]['user_info']['user_id']
self.name = json["anchor"]['user_info']['name']
if "user_id" in json:
self.ID = json["user_id"]
if "user_name" in json:
self.name = json["user_name"]
if self.type is None:
self.type = 0
if isinstance(self.level, str):
self.level = int(self.level)
def __str__(self):
if self.level == 0:
if self.type == 1:
return "[房管]{}".format(self.name)
elif self.type == 3:
return "[主播]{}".format(self.name)
else:
return "{}".format(self.name)
else:
if self.type != 0:
return "[{}{}]{}".format(self.brand, self.level, self.name)
return "<{}{}>{}".format(self.brand, self.level, self.name)
def __unicode__(self):
return self.__str__()
def __repr__(self):
return "西瓜用户【{}(ID:{})】".format(self.name, self.ID)

44
User.py Normal file
View File

@ -0,0 +1,44 @@
class User:
ID: int = 0
name: str = ""
brand: str = ""
level: int = 0
type: int = 0
def __init__(self, json=None):
if json:
self.parse(json)
def parse(self, json):
if "Msg" in json:
if "user" in json["Msg"]:
self.ID = json["Msg"]['user']['user_id']
self.name = json["Msg"]['user']['name']
self.type = json["Msg"]['user']['user_type']
if "discipulus_info" in json["Msg"]:
self.level = json["Msg"]["discipulus_info"]["level"]
self.brand = json["Msg"]["discipulus_info"]["discipulus_group_title"]
elif "data" in json:
if "anchorInfo" in json["data"]:
self.ID = json["data"]['anchorInfo']['user_id']
self.name = json["data"]['anchorInfo']['name']
self.type = 0
if self.type is None:
self.type = 0
def __str__(self):
if self.level == 0:
if self.type == 1:
return "[房管]{}".format(self.name)
elif self.type == 2:
return "[主播]{}".format(self.name)
else:
return "{}".format(self.name)
else:
if self.type != 0:
return "[{}{}]{}".format(self.brand, self.level, self.name)
return "<{}{}>{}".format(self.brand,self.level,self.name)
def __unicode__(self):
return self.__str__()

View File

@ -1,198 +0,0 @@
import os
from glob import glob
from time import sleep
from flask_cors import CORS
from flask import Flask, jsonify, request, render_template, Response, send_file
import Common
import threading
from liveDownloader import run as RUN
app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False
CORS(app, supports_credentials=True)
@app.route("/")
def index():
return render_template("index.html")
@app.route("/config", methods=["GET"])
def readConfig():
config = Common.config.copy()
return jsonify(config)
@app.route("/config", methods=["POST"])
def writeConfig():
# TODO : 完善
Common.appendOperation("更新配置")
Common.reloadConfig()
return jsonify({"message": "ok", "code": 200, "status": 0, "data": request.form})
@app.route("/force/not/upload", methods=["POST"])
def toggleForceNotUpload():
Common.forceNotUpload = not Common.forceNotUpload
Common.appendOperation("将强制不上传的值改为:{}".format(Common.forceNotUpload))
return jsonify({"message": "ok", "code": 200, "status": 0, "data": {
"forceNotUpload": Common.forceNotUpload,
}})
@app.route("/force/not/encode", methods=["POST"])
def toggleForceNotEncode():
Common.forceNotEncode = not Common.forceNotEncode
Common.appendOperation("将强制不编码的值改为:{}".format(Common.forceNotEncode))
return jsonify({"message": "ok", "code": 200, "status": 0, "data": {
"forceNotEncode": Common.forceNotEncode,
}})
@app.route("/force/not/download", methods=["POST"])
def toggleForceNotDownload():
Common.forceNotDownload = not Common.forceNotDownload
Common.appendOperation("将强制不下载的值改为:{}".format(Common.forceNotDownload))
return jsonify({"message": "ok", "code": 200, "status": 0, "data": {
"forceNotDownload": Common.forceNotDownload,
}})
@app.route("/force/not/broadcast", methods=["POST"])
def toggleForceNotBroadcast():
Common.forceNotBroadcasting = not Common.forceNotBroadcasting
return jsonify({"message": "ok", "code": 200, "status": 0, "data": {
"forceNotBroadcasting": Common.forceNotBroadcasting,
}})
@app.route("/force/start/encode", methods=["POST"])
def toggleForceStartEncodeThread():
Common.forceStartEncodeThread = True
Common.appendOperation("强制运行编码线程")
return jsonify({"message": "ok", "code": 200, "status": 0, "data": {
}})
@app.route("/force/start/upload", methods=["POST"])
def toggleForceStartUploadThread():
Common.forceStartUploadThread = True
Common.appendOperation("强制运行上传线程")
return jsonify({"message": "ok", "code": 200, "status": 0, "data": {
}})
@app.route("/force/start/clean", methods=["POST"])
def startForceCleanDisk():
Common.doClean(True)
Common.appendOperation("强制执行清理程序")
return jsonify({"message": "ok", "code": 200, "status": 0, "data": {
}})
@app.route("/encode/insert", methods=["POST"])
def insertEncode():
if "filename" in request.form and os.path.exists(request.form["filename"]):
Common.appendOperation("添加编码文件:{}".format(request.form["filename"]))
Common.encodeQueue.put(request.form["filename"])
return jsonify({"message": "ok", "code": 200, "status": 0})
else:
return jsonify({"message": "no filename specific", "code": 400, "status": 1})
@app.route("/upload/insert", methods=["POST"])
def insertUpload():
if "filename" in request.form and os.path.exists(request.form["filename"]):
Common.appendOperation("添加上传文件:{}".format(request.form["filename"]))
Common.uploadQueue.put(request.form["filename"])
return jsonify({"message": "ok", "code": 200, "status": 0})
else:
return jsonify({"message": "no filename specific", "code": 400, "status": 1})
@app.route("/upload/discard", methods=["POST"])
def discardUpload():
Common.uploadQueue.empty()
Common.b.clear()
return jsonify({"message": "ok", "code": 200, "status": 0})
@app.route("/upload/finish", methods=["POST"])
def finishUpload():
Common.appendOperation("设置当前已完成上传")
Common.uploadQueue.put(True)
return jsonify({"message": "ok", "code": 200, "status": 0})
@app.route("/stats", methods=["GET"])
def getAllStats():
return jsonify({"message": "ok", "code": 200, "status": 0, "data": Common.collectInfomation()})
@app.route("/stats/device", methods=["GET"])
def getDeviceStatus():
return jsonify({"message": "ok", "code": 200, "status": 0, "data": {
"status": Common.getCurrentStatus(),
}})
@app.route("/stats/config", methods=["GET"])
def getConfigStats():
return jsonify({"message": "ok", "code": 200, "status": 0, "data": {
"config": {
"forceNotBroadcasting": Common.forceNotBroadcasting,
"forceNotDownload": Common.forceNotDownload,
"forceNotUpload": Common.forceNotUpload,
"forceNotEncode": Common.forceNotEncode,
"downloadOnly": Common.config['dlO'],
}
}})
@app.route("/account/reLogin", methods=["POST"])
def accountRelogin():
res = Common.loginBilibili(True)
return jsonify({"message": "ok", "code": 200, "status": 0, "data": {"result": res}})
@app.route("/files/", methods=["GET"])
def fileIndex():
a = []
for i in (glob("*.mp4") + glob("*.flv")):
a.append({
"name": i,
"size": Common.parseSize(os.path.getsize(i))
})
return render_template("files.html", files=a)
@app.route("/files/download/<path>", methods=["GET"])
def fileDownload(path):
if not (".mp4" in path or ".flv" in path):
return Response(status=404)
if os.path.exists(path):
return send_file(path, as_attachment=True)
else:
return Response(status=404)
def SubThread():
t = threading.Thread(target=RUN, args=())
t.setDaemon(True)
t.start()
while True:
if t.is_alive():
sleep(240)
else:
t = threading.Thread(target=RUN, args=())
t.setDaemon(True)
t.start()
if not app.debug:
p = threading.Thread(target=SubThread)
p.setDaemon(True)
p.start()
if __name__ == "__main__":
app.run()

View File

@ -2,20 +2,14 @@ import os
import sys
import time
import requests
from Gift import Gift
from User import User
from Struct.MemberMsg import MemberMsg
from Struct.User import User
from Struct.Gift import Gift
from Struct.Chat import Chat
from Struct.Lottery import Lottery
from Chat import Chat
from api import XiGuaLiveApi as Api
from api import public_hello
import msvcrt
import ctypes
SHOW_ALL = False
def readInput(caption, default, timeout: int = 5):
start_time = time.time()
@ -23,7 +17,7 @@ def readInput(caption, default, timeout: int = 5):
input = ''
while True:
if msvcrt.kbhit():
chr = msvcrt.getwche()
chr = msvcrt.getche()
if ord(chr) == 13: # enter_key
break
elif ord(chr) == 27:
@ -32,15 +26,11 @@ def readInput(caption, default, timeout: int = 5):
if input != "":
input = input[:-1]
msvcrt.putch(b" ")
msvcrt.putch(b" ")
msvcrt.putch(b"\b")
msvcrt.putch(b"\b")
if len(input) == 0:
start_time = time.time()
elif 32 > ord(chr) or 255 > ord(chr) > 126: # space_char
continue
else:
input += chr
elif 32 <= ord(chr) <= 126: # space_char
input += chr.decode("utf8")
if len(input) == 0 and (time.time() - start_time) > timeout:
break
@ -78,9 +68,8 @@ FOREGROUND_YELLOW = 0x0e # yellow.
FOREGROUND_WHITE = 0x0f # white.
# Windows CMD命令行 背景颜色定义 background colors
BACKGROUND_BLACK = 0x00 # dark blue.
BACKGROUND_DARKBLUE = 0x10 # dark blue.
BACKGROUND_DARKGREEN = 0x20 # dark green.
BACKGROUND_BLUE = 0x10 # dark blue.
BACKGROUND_GREEN = 0x20 # dark green.
BACKGROUND_DARKSKYBLUE = 0x30 # dark skyblue.
BACKGROUND_DARKRED = 0x40 # dark red.
BACKGROUND_DARKPINK = 0x50 # dark pink.
@ -102,7 +91,7 @@ def set_cmd_text_color(color, handle=std_out_handle):
def resetColor():
set_cmd_text_color(BACKGROUND_BLACK | FOREGROUND_WHITE)
set_cmd_text_color(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
class WinMain(Api):
@ -112,74 +101,56 @@ class WinMain(Api):
self._tmp += 1
if self._tmp > 10:
self._tmp = 0
if self._tmp < 5:
return "{} 的直播间 --弹幕助手 by JerryYan".format(self.broadcaster)
if self._tmp < 5 :
return "{} {} --弹幕助手 by JerryYan".format(self.roomLiver, "的直播间")
else:
if self.roomPopularity == 0:
self._tmp = 0
return self.getTitle()
else:
return "人气:{} --弹幕助手 by JerryYan".format(self.roomPopularity)
if self.roomMember > 0:
return "观看:{} 人气:{} --弹幕助手 by JerryYan".format(self.roomMember, self.roomPopularity)
else:
return "观看:待刷新 人气:{} --弹幕助手 by JerryYan".format(self.roomPopularity)
def onMessage(self, msg: str):
if SHOW_ALL:
set_cmd_text_color(BACKGROUND_BLACK | FOREGROUND_DARKGRAY)
print("消息 : ", msg, end="")
set_cmd_text_color(FOREGROUND_DARKGRAY)
print("消息:", msg)
resetColor()
print()
def onJoin(self, user: User):
set_cmd_text_color(BACKGROUND_WHITE | FOREGROUND_BLACK)
print("欢迎", user, "加入了粉丝团", end="")
print("感谢", user, "加入了粉丝团")
resetColor()
print()
def onSubscribe(self, user: User):
if SHOW_ALL:
set_cmd_text_color(BACKGROUND_BLACK | FOREGROUND_DARKGRAY)
print("用户", user, "关注了主播", end="")
resetColor()
print()
return
def onEnter(self, msg:MemberMsg):
if SHOW_ALL:
set_cmd_text_color(BACKGROUND_BLACK | FOREGROUND_DARKGRAY)
print("提示 :", msg, end="")
def onEnter(self, user: User, content: str == ""):
if content == "":
if user.name == "三国空白" or user.name == "四维v":
set_cmd_text_color(FOREGROUND_DARKGRAY)
print("消息:", user, "进入直播间")
resetColor()
else:
set_cmd_text_color(FOREGROUND_DARKGRAY)
print("消息:", content.format(user))
resetColor()
print()
def onChat(self, chat: Chat):
if SHOW_ALL:
set_cmd_text_color(BACKGROUND_BLACK | FOREGROUND_WHITE)
if not chat.isFiltered:
print(chat, end="")
resetColor()
print()
def onLottery(self, i:Lottery):
set_cmd_text_color(FOREGROUND_WHITE | BACKGROUND_DARKGRAY)
print(i, end="")
resetColor()
print()
print(chat)
def onPresent(self, gift: Gift):
if SHOW_ALL:
set_cmd_text_color(BACKGROUND_BLACK | FOREGROUND_DARKGRAY)
print("连击 :", gift)
resetColor()
return
def onPresentEnd(self, gift: Gift):
set_cmd_text_color(BACKGROUND_WHITE | FOREGROUND_BLACK)
print("感谢", gift, end="")
print("感谢", gift)
resetColor()
print()
def onLike(self, user: User):
if SHOW_ALL:
set_cmd_text_color(BACKGROUND_BLACK | FOREGROUND_DARKGRAY)
print("用户", user, "点了喜欢", end="")
resetColor()
print()
return
def onLeave(self, json: any):
return
@ -190,47 +161,34 @@ def warning(*args):
if __name__ == "__main__":
name = "97621754276"
if len(sys.argv) > 2:
if sys.argv[-1] == "a":
SHOW_ALL = True
name = sys.argv[1]
room = 97621754276 # 永恒
# room = 75366565294
# room = 83940182312 #Dae
resetColor()
public_hello()
print("搜索【", name, "", end="\t", flush=True)
api = WinMain(name)
if not api.isValidUser:
input("用户不存在")
print("西瓜直播弹幕助手 by JerryYan")
if len(sys.argv) > 1:
room = int(sys.argv[1])
else:
try:
room = int(readInput("请输入房间号,默认为永恒的直播间", room, 3))
except ValueError:
pass
api = WinMain(room)
print("进入", api.roomLiver, "的直播间")
if not api.isValidRoom:
input("房间不存在")
sys.exit()
print("OK")
print(api.broadcaster.__repr__())
print("更新房间信息,请稍后", end="\t", flush=True)
os.system("title {}".format(api.getTitle()))
if api.updRoomInfo(True):
print("OK")
else:
print("FAIL")
print("更新房间礼物信息", end="\t", flush=True)
__res = api.updGiftInfo()
if __res < 0:
print("FAIL")
else:
print('OK\n礼物种数:', __res)
print("=" * 30)
while True:
if api.isLive:
os.system("title {}".format(api.getTitle()))
try:
os.system("title {}".format(api.getTitle()))
api.getDanmaku()
except requests.exceptions.BaseHTTPError:
print("网络错误,请确认网络")
time.sleep(5)
except Exception as e:
print(e.__str__())
warning(e)
time.sleep(1)
else:
set_cmd_text_color(FOREGROUND_RED)
print("主播未开播等待1分钟后重试")
resetColor()
time.sleep(60)
api.updRoomInfo(True)
api.updRoomInfo()

View File

@ -1,33 +0,0 @@
# -*- mode: python -*-
block_cipher = None
a = Analysis(['WinMain.py'],
pathex=['E:\\XiGuaLiveDanmakuHelper',r'C:\\Program Files (x86)\\Windows Kits\\10\\Redist\\10.0.17763.0\\ucrt\\DLLs\\x86'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=["xml", "_tkinter", "pydoc", "lib2to3"],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='西瓜直播礼物助手',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=False,
runtime_tmpdir=None,
console=True,
icon='./ico.ico' )

View File

@ -1,122 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: XiguaGift.proto
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='XiguaGift.proto',
package='',
syntax='proto2',
serialized_options=None,
serialized_pb=b'\n\x0fXiguaGift.proto\" \n\x04Gift\x12\n\n\x02id\x18\x01 \x02(\t\x12\x0c\n\x04name\x18\x02 \x02(\t\"+\n\x08GiftPack\x12\n\n\x02id\x18\x01 \x02(\x05\x12\x13\n\x04gift\x18\x02 \x02(\x0b\x32\x05.Gift'
)
_GIFT = _descriptor.Descriptor(
name='Gift',
full_name='Gift',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='id', full_name='Gift.id', index=0,
number=1, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='name', full_name='Gift.name', index=1,
number=2, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=19,
serialized_end=51,
)
_GIFTPACK = _descriptor.Descriptor(
name='GiftPack',
full_name='GiftPack',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='id', full_name='GiftPack.id', index=0,
number=1, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='gift', full_name='GiftPack.gift', index=1,
number=2, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=53,
serialized_end=96,
)
_GIFTPACK.fields_by_name['gift'].message_type = _GIFT
DESCRIPTOR.message_types_by_name['Gift'] = _GIFT
DESCRIPTOR.message_types_by_name['GiftPack'] = _GIFTPACK
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
Gift = _reflection.GeneratedProtocolMessageType('Gift', (_message.Message,), {
'DESCRIPTOR' : _GIFT,
'__module__' : 'XiguaGift_pb2'
# @@protoc_insertion_point(class_scope:Gift)
})
_sym_db.RegisterMessage(Gift)
GiftPack = _reflection.GeneratedProtocolMessageType('GiftPack', (_message.Message,), {
'DESCRIPTOR' : _GIFTPACK,
'__module__' : 'XiguaGift_pb2'
# @@protoc_insertion_point(class_scope:GiftPack)
})
_sym_db.RegisterMessage(GiftPack)
# @@protoc_insertion_point(module_scope)

View File

@ -1,797 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: XiguaMessage.proto
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
import XiguaUser_pb2 as XiguaUser__pb2
import XiguaGift_pb2 as XiguaGift__pb2
DESCRIPTOR = _descriptor.FileDescriptor(
name='XiguaMessage.proto',
package='',
syntax='proto2',
serialized_options=None,
serialized_pb=b'\n\x12XiguaMessage.proto\x1a\x0fXiguaUser.proto\x1a\x0fXiguaGift.proto\"*\n\x07Message\x12\x1f\n\ncommonInfo\x18\x01 \x02(\x0b\x32\x0b.CommonInfo\"f\n\x0f\x46\x61nsClubMessage\x12\x1f\n\ncommonInfo\x18\x01 \x02(\x0b\x32\x0b.CommonInfo\x12\x0c\n\x04type\x18\x02 \x02(\x05\x12\x0f\n\x07\x63ontent\x18\x03 \x02(\t\x12\x13\n\x04user\x18\x04 \x02(\x0b\x32\x05.User\"U\n\x14\x46\x61nsClubStatsMessage\x12\x1f\n\ncommonInfo\x18\x01 \x02(\x0b\x32\x0b.CommonInfo\x12\r\n\x05title\x18\x02 \x02(\t\x12\r\n\x05\x63ount\x18\x03 \x02(\x05\"]\n\x0eUserSeqMessage\x12\x1f\n\ncommonInfo\x18\x01 \x02(\x0b\x32\x0b.CommonInfo\x12\x16\n\x0epopularityText\x18\x04 \x02(\t\x12\x12\n\npopularity\x18\x06 \x02(\x05\"D\n\x10\x44\x61ilyRankMessage\x12\x1f\n\ncommonInfo\x18\x01 \x02(\x0b\x32\x0b.CommonInfo\x12\x0f\n\x07ranking\x18\n \x02(\x05\"T\n\x0b\x43hatMessage\x12\x1f\n\ncommonInfo\x18\x01 \x02(\x0b\x32\x0b.CommonInfo\x12\x13\n\x04user\x18\x02 \x02(\x0b\x32\x05.User\x12\x0f\n\x07\x63ontent\x18\x03 \x02(\t\"]\n\rMemberMessage\x12\x1f\n\ncommonInfo\x18\x01 \x02(\x0b\x32\x0b.CommonInfo\x12\x13\n\x04user\x18\x02 \x02(\x0b\x32\x05.User\x12\x16\n\x0epopularityText\x18\x0e \x02(\t\"\xa1\x01\n\x0bGiftMessage\x12\x1f\n\ncommonInfo\x18\x01 \x02(\x0b\x32\x0b.CommonInfo\x12\x0e\n\x06giftId\x18\x02 \x02(\x05\x12\x10\n\x08\x63ontent4\x18\x04 \x02(\x05\x12\x10\n\x08repeated\x18\x05 \x02(\x05\x12\r\n\x05\x63ombo\x18\x06 \x02(\x05\x12\x13\n\x04user\x18\x07 \x01(\x0b\x32\x05.User\x12\x19\n\nisFinished\x18\t \x01(\x08:\x05\x66\x61lse\"f\n\rSocialMessage\x12\x1f\n\ncommonInfo\x18\x01 \x02(\x0b\x32\x0b.CommonInfo\x12\x13\n\x04user\x18\x02 \x02(\x0b\x32\x05.User\x12\x0c\n\x04int4\x18\x04 \x02(\x05\x12\x11\n\tfansCount\x18\x06 \x02(\x05\"*\n\x05Style\x12\r\n\x05\x63olor\x18\x01 \x01(\t\x12\x12\n\nfontWeight\x18\x04 \x01(\x05\"q\n\x06Params\x12\x0c\n\x04type\x18\x01 \x02(\x05\x12\x15\n\x05style\x18\x02 \x01(\x0b\x32\x06.Style\x12\x0e\n\x06string\x18\x0b \x01(\t\x12\x18\n\x05users\x18\x15 \x01(\x0b\x32\t.UserPack\x12\x18\n\x05gifts\x18\x16 \x01(\x0b\x32\t.GiftPack\"_\n\x0b\x44isplayText\x12\x0e\n\x06method\x18\x01 \x02(\t\x12\x0e\n\x06\x66ormat\x18\x02 \x02(\t\x12\x17\n\x07\x62gStyle\x18\x03 \x01(\x0b\x32\x06.Style\x12\x17\n\x06params\x18\x04 \x02(\x0b\x32\x07.Params\"\x87\x01\n\nCommonInfo\x12\x0e\n\x06method\x18\x01 \x02(\t\x12\x0e\n\x06msg_id\x18\x02 \x02(\x05\x12\x0f\n\x07room_id\x18\x03 \x02(\x05\x12\x13\n\x0b\x63reate_time\x18\x04 \x02(\x05\x12\x10\n\x08someEnum\x18\x06 \x01(\x05\x12!\n\x0b\x64isplayText\x18\x08 \x01(\x0b\x32\x0c.DisplayText'
,
dependencies=[XiguaUser__pb2.DESCRIPTOR,XiguaGift__pb2.DESCRIPTOR,])
_MESSAGE = _descriptor.Descriptor(
name='Message',
full_name='Message',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='commonInfo', full_name='Message.commonInfo', index=0,
number=1, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=56,
serialized_end=98,
)
_FANSCLUBMESSAGE = _descriptor.Descriptor(
name='FansClubMessage',
full_name='FansClubMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='commonInfo', full_name='FansClubMessage.commonInfo', index=0,
number=1, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='type', full_name='FansClubMessage.type', index=1,
number=2, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='content', full_name='FansClubMessage.content', index=2,
number=3, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='user', full_name='FansClubMessage.user', index=3,
number=4, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=100,
serialized_end=202,
)
_FANSCLUBSTATSMESSAGE = _descriptor.Descriptor(
name='FansClubStatsMessage',
full_name='FansClubStatsMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='commonInfo', full_name='FansClubStatsMessage.commonInfo', index=0,
number=1, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='title', full_name='FansClubStatsMessage.title', index=1,
number=2, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='count', full_name='FansClubStatsMessage.count', index=2,
number=3, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=204,
serialized_end=289,
)
_USERSEQMESSAGE = _descriptor.Descriptor(
name='UserSeqMessage',
full_name='UserSeqMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='commonInfo', full_name='UserSeqMessage.commonInfo', index=0,
number=1, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='popularityText', full_name='UserSeqMessage.popularityText', index=1,
number=4, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='popularity', full_name='UserSeqMessage.popularity', index=2,
number=6, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=291,
serialized_end=384,
)
_DAILYRANKMESSAGE = _descriptor.Descriptor(
name='DailyRankMessage',
full_name='DailyRankMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='commonInfo', full_name='DailyRankMessage.commonInfo', index=0,
number=1, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='ranking', full_name='DailyRankMessage.ranking', index=1,
number=10, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=386,
serialized_end=454,
)
_CHATMESSAGE = _descriptor.Descriptor(
name='ChatMessage',
full_name='ChatMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='commonInfo', full_name='ChatMessage.commonInfo', index=0,
number=1, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='user', full_name='ChatMessage.user', index=1,
number=2, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='content', full_name='ChatMessage.content', index=2,
number=3, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=456,
serialized_end=540,
)
_MEMBERMESSAGE = _descriptor.Descriptor(
name='MemberMessage',
full_name='MemberMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='commonInfo', full_name='MemberMessage.commonInfo', index=0,
number=1, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='user', full_name='MemberMessage.user', index=1,
number=2, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='popularityText', full_name='MemberMessage.popularityText', index=2,
number=14, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=542,
serialized_end=635,
)
_GIFTMESSAGE = _descriptor.Descriptor(
name='GiftMessage',
full_name='GiftMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='commonInfo', full_name='GiftMessage.commonInfo', index=0,
number=1, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='giftId', full_name='GiftMessage.giftId', index=1,
number=2, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='content4', full_name='GiftMessage.content4', index=2,
number=4, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='repeated', full_name='GiftMessage.repeated', index=3,
number=5, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='combo', full_name='GiftMessage.combo', index=4,
number=6, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='user', full_name='GiftMessage.user', index=5,
number=7, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='isFinished', full_name='GiftMessage.isFinished', index=6,
number=9, type=8, cpp_type=7, label=1,
has_default_value=True, default_value=False,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=638,
serialized_end=799,
)
_SOCIALMESSAGE = _descriptor.Descriptor(
name='SocialMessage',
full_name='SocialMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='commonInfo', full_name='SocialMessage.commonInfo', index=0,
number=1, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='user', full_name='SocialMessage.user', index=1,
number=2, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='int4', full_name='SocialMessage.int4', index=2,
number=4, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='fansCount', full_name='SocialMessage.fansCount', index=3,
number=6, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=801,
serialized_end=903,
)
_STYLE = _descriptor.Descriptor(
name='Style',
full_name='Style',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='color', full_name='Style.color', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='fontWeight', full_name='Style.fontWeight', index=1,
number=4, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=905,
serialized_end=947,
)
_PARAMS = _descriptor.Descriptor(
name='Params',
full_name='Params',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='type', full_name='Params.type', index=0,
number=1, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='style', full_name='Params.style', index=1,
number=2, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='string', full_name='Params.string', index=2,
number=11, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='users', full_name='Params.users', index=3,
number=21, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='gifts', full_name='Params.gifts', index=4,
number=22, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=949,
serialized_end=1062,
)
_DISPLAYTEXT = _descriptor.Descriptor(
name='DisplayText',
full_name='DisplayText',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='method', full_name='DisplayText.method', index=0,
number=1, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='format', full_name='DisplayText.format', index=1,
number=2, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='bgStyle', full_name='DisplayText.bgStyle', index=2,
number=3, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='params', full_name='DisplayText.params', index=3,
number=4, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=1064,
serialized_end=1159,
)
_COMMONINFO = _descriptor.Descriptor(
name='CommonInfo',
full_name='CommonInfo',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='method', full_name='CommonInfo.method', index=0,
number=1, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='msg_id', full_name='CommonInfo.msg_id', index=1,
number=2, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='room_id', full_name='CommonInfo.room_id', index=2,
number=3, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='create_time', full_name='CommonInfo.create_time', index=3,
number=4, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='someEnum', full_name='CommonInfo.someEnum', index=4,
number=6, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='displayText', full_name='CommonInfo.displayText', index=5,
number=8, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=1162,
serialized_end=1297,
)
_MESSAGE.fields_by_name['commonInfo'].message_type = _COMMONINFO
_FANSCLUBMESSAGE.fields_by_name['commonInfo'].message_type = _COMMONINFO
_FANSCLUBMESSAGE.fields_by_name['user'].message_type = XiguaUser__pb2._USER
_FANSCLUBSTATSMESSAGE.fields_by_name['commonInfo'].message_type = _COMMONINFO
_USERSEQMESSAGE.fields_by_name['commonInfo'].message_type = _COMMONINFO
_DAILYRANKMESSAGE.fields_by_name['commonInfo'].message_type = _COMMONINFO
_CHATMESSAGE.fields_by_name['commonInfo'].message_type = _COMMONINFO
_CHATMESSAGE.fields_by_name['user'].message_type = XiguaUser__pb2._USER
_MEMBERMESSAGE.fields_by_name['commonInfo'].message_type = _COMMONINFO
_MEMBERMESSAGE.fields_by_name['user'].message_type = XiguaUser__pb2._USER
_GIFTMESSAGE.fields_by_name['commonInfo'].message_type = _COMMONINFO
_GIFTMESSAGE.fields_by_name['user'].message_type = XiguaUser__pb2._USER
_SOCIALMESSAGE.fields_by_name['commonInfo'].message_type = _COMMONINFO
_SOCIALMESSAGE.fields_by_name['user'].message_type = XiguaUser__pb2._USER
_PARAMS.fields_by_name['style'].message_type = _STYLE
_PARAMS.fields_by_name['users'].message_type = XiguaUser__pb2._USERPACK
_PARAMS.fields_by_name['gifts'].message_type = XiguaGift__pb2._GIFTPACK
_DISPLAYTEXT.fields_by_name['bgStyle'].message_type = _STYLE
_DISPLAYTEXT.fields_by_name['params'].message_type = _PARAMS
_COMMONINFO.fields_by_name['displayText'].message_type = _DISPLAYTEXT
DESCRIPTOR.message_types_by_name['Message'] = _MESSAGE
DESCRIPTOR.message_types_by_name['FansClubMessage'] = _FANSCLUBMESSAGE
DESCRIPTOR.message_types_by_name['FansClubStatsMessage'] = _FANSCLUBSTATSMESSAGE
DESCRIPTOR.message_types_by_name['UserSeqMessage'] = _USERSEQMESSAGE
DESCRIPTOR.message_types_by_name['DailyRankMessage'] = _DAILYRANKMESSAGE
DESCRIPTOR.message_types_by_name['ChatMessage'] = _CHATMESSAGE
DESCRIPTOR.message_types_by_name['MemberMessage'] = _MEMBERMESSAGE
DESCRIPTOR.message_types_by_name['GiftMessage'] = _GIFTMESSAGE
DESCRIPTOR.message_types_by_name['SocialMessage'] = _SOCIALMESSAGE
DESCRIPTOR.message_types_by_name['Style'] = _STYLE
DESCRIPTOR.message_types_by_name['Params'] = _PARAMS
DESCRIPTOR.message_types_by_name['DisplayText'] = _DISPLAYTEXT
DESCRIPTOR.message_types_by_name['CommonInfo'] = _COMMONINFO
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
Message = _reflection.GeneratedProtocolMessageType('Message', (_message.Message,), {
'DESCRIPTOR' : _MESSAGE,
'__module__' : 'XiguaMessage_pb2'
# @@protoc_insertion_point(class_scope:Message)
})
_sym_db.RegisterMessage(Message)
FansClubMessage = _reflection.GeneratedProtocolMessageType('FansClubMessage', (_message.Message,), {
'DESCRIPTOR' : _FANSCLUBMESSAGE,
'__module__' : 'XiguaMessage_pb2'
# @@protoc_insertion_point(class_scope:FansClubMessage)
})
_sym_db.RegisterMessage(FansClubMessage)
FansClubStatsMessage = _reflection.GeneratedProtocolMessageType('FansClubStatsMessage', (_message.Message,), {
'DESCRIPTOR' : _FANSCLUBSTATSMESSAGE,
'__module__' : 'XiguaMessage_pb2'
# @@protoc_insertion_point(class_scope:FansClubStatsMessage)
})
_sym_db.RegisterMessage(FansClubStatsMessage)
UserSeqMessage = _reflection.GeneratedProtocolMessageType('UserSeqMessage', (_message.Message,), {
'DESCRIPTOR' : _USERSEQMESSAGE,
'__module__' : 'XiguaMessage_pb2'
# @@protoc_insertion_point(class_scope:UserSeqMessage)
})
_sym_db.RegisterMessage(UserSeqMessage)
DailyRankMessage = _reflection.GeneratedProtocolMessageType('DailyRankMessage', (_message.Message,), {
'DESCRIPTOR' : _DAILYRANKMESSAGE,
'__module__' : 'XiguaMessage_pb2'
# @@protoc_insertion_point(class_scope:DailyRankMessage)
})
_sym_db.RegisterMessage(DailyRankMessage)
ChatMessage = _reflection.GeneratedProtocolMessageType('ChatMessage', (_message.Message,), {
'DESCRIPTOR' : _CHATMESSAGE,
'__module__' : 'XiguaMessage_pb2'
# @@protoc_insertion_point(class_scope:ChatMessage)
})
_sym_db.RegisterMessage(ChatMessage)
MemberMessage = _reflection.GeneratedProtocolMessageType('MemberMessage', (_message.Message,), {
'DESCRIPTOR' : _MEMBERMESSAGE,
'__module__' : 'XiguaMessage_pb2'
# @@protoc_insertion_point(class_scope:MemberMessage)
})
_sym_db.RegisterMessage(MemberMessage)
GiftMessage = _reflection.GeneratedProtocolMessageType('GiftMessage', (_message.Message,), {
'DESCRIPTOR' : _GIFTMESSAGE,
'__module__' : 'XiguaMessage_pb2'
# @@protoc_insertion_point(class_scope:GiftMessage)
})
_sym_db.RegisterMessage(GiftMessage)
SocialMessage = _reflection.GeneratedProtocolMessageType('SocialMessage', (_message.Message,), {
'DESCRIPTOR' : _SOCIALMESSAGE,
'__module__' : 'XiguaMessage_pb2'
# @@protoc_insertion_point(class_scope:SocialMessage)
})
_sym_db.RegisterMessage(SocialMessage)
Style = _reflection.GeneratedProtocolMessageType('Style', (_message.Message,), {
'DESCRIPTOR' : _STYLE,
'__module__' : 'XiguaMessage_pb2'
# @@protoc_insertion_point(class_scope:Style)
})
_sym_db.RegisterMessage(Style)
Params = _reflection.GeneratedProtocolMessageType('Params', (_message.Message,), {
'DESCRIPTOR' : _PARAMS,
'__module__' : 'XiguaMessage_pb2'
# @@protoc_insertion_point(class_scope:Params)
})
_sym_db.RegisterMessage(Params)
DisplayText = _reflection.GeneratedProtocolMessageType('DisplayText', (_message.Message,), {
'DESCRIPTOR' : _DISPLAYTEXT,
'__module__' : 'XiguaMessage_pb2'
# @@protoc_insertion_point(class_scope:DisplayText)
})
_sym_db.RegisterMessage(DisplayText)
CommonInfo = _reflection.GeneratedProtocolMessageType('CommonInfo', (_message.Message,), {
'DESCRIPTOR' : _COMMONINFO,
'__module__' : 'XiguaMessage_pb2'
# @@protoc_insertion_point(class_scope:CommonInfo)
})
_sym_db.RegisterMessage(CommonInfo)
# @@protoc_insertion_point(module_scope)

View File

@ -1,727 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: XiguaUser.proto
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='XiguaUser.proto',
package='',
syntax='proto2',
serialized_options=None,
serialized_pb=b'\n\x0fXiguaUser.proto\"\x1f\n\x08UserPack\x12\x13\n\x04user\x18\x01 \x02(\x0b\x32\x05.User\"\xb6\x01\n\x05\x42\x61\x64ge\x12\x0b\n\x03url\x18\x01 \x03(\t\x12\x0e\n\x06height\x18\x03 \x01(\x05\x12\r\n\x05width\x18\x04 \x01(\x05\x12\x0c\n\x04type\x18\x06 \x01(\x05\x12\x0f\n\x07\x63lickTo\x18\x07 \x01(\t\x12\'\n\x0b\x66\x61nClubText\x18\x08 \x01(\x0b\x32\x12.Badge.FanClubText\x1a\x39\n\x0b\x46\x61nClubText\x12\x0c\n\x04text\x18\x01 \x02(\t\x12\r\n\x05\x63olor\x18\x02 \x01(\t\x12\r\n\x05level\x18\x03 \x02(\x05\"y\n\x0c\x46\x61nsClubPack\x12(\n\x08\x66\x61nsClub\x18\x01 \x02(\x0b\x32\x16.FansClubPack.FansClub\x1a?\n\x08\x46\x61nsClub\x12\x0f\n\x05title\x18\x01 \x02(\t:\x00\x12\x10\n\x05level\x18\x02 \x02(\x05:\x01\x30\x12\x10\n\x08someEnum\x18\x03 \x01(\x05\"\xd8\x05\n\x04User\x12\n\n\x02id\x18\x01 \x02(\x03\x12\x10\n\x08nickname\x18\x03 \x02(\t\x12\x0e\n\x06gender\x18\x04 \x02(\x05\x12!\n\x0b\x61vatarThumb\x18\t \x02(\x0b\x32\x0c.User.Avatar\x12\"\n\x0c\x61vatarMedium\x18\n \x01(\x0b\x32\x0c.User.Avatar\x12!\n\x0b\x61vatarLarge\x18\x0b \x01(\x0b\x32\x0c.User.Avatar\x12\x15\n\x05\x62\x61\x64ge\x18\x15 \x03(\x0b\x32\x06.Badge\x12\x1c\n\x06\x66ollow\x18\x16 \x01(\x0b\x32\x0c.User.Follow\x12 \n\x08payGrade\x18\x17 \x02(\x0b\x32\x0e.User.PayGrade\x12\x1f\n\x08\x66\x61nsClub\x18\x18 \x02(\x0b\x32\r.FansClubPack\x12\x11\n\ttotalPaid\x18\" \x02(\x05\x1a!\n\x06\x41vatar\x12\x0b\n\x03url\x18\x01 \x02(\t\x12\n\n\x02id\x18\x02 \x01(\t\x1a\x33\n\x06\x46ollow\x12\x14\n\tfollowing\x18\x01 \x01(\x05:\x01\x30\x12\x13\n\x08\x66ollower\x18\x02 \x01(\x05:\x01\x30\x1a\x9c\x01\n\x08PayGrade\x12\x0f\n\x07\x63urrent\x18\x01 \x02(\x05\x12\r\n\x05level\x18\x06 \x02(\x05\x12\x18\n\x10\x63urrentLevelNeed\x18\n \x01(\x05\x12\x15\n\rnextLevelNeed\x18\x0b \x01(\x05\x12\x0f\n\x07\x63ontent\x18\r \x01(\t\x12\x15\n\x05\x62\x61\x64ge\x18\x13 \x02(\x0b\x32\x06.Badge\x12\x17\n\x0ftoNextLevelNeed\x18\x15 \x01(\x05\x1a#\n\nHonorLevel\x12\x15\n\x05\x62\x61\x64ge\x18\x13 \x02(\x0b\x32\x06.Badge\x1a\x90\x01\n\x05Noble\x12\x0f\n\x07\x63ontent\x18\x04 \x02(\t\x12)\n\x07\x62oarder\x18\x08 \x01(\x0b\x32\x18.User.Noble.NobleBoarder\x1aK\n\x0cNobleBoarder\x12\x0f\n\x07urlList\x18\x01 \x03(\t\x12\x0b\n\x03uri\x18\x02 \x02(\t\x12\x0e\n\x06height\x18\x03 \x01(\x05\x12\r\n\x05width\x18\x04 \x01(\x05'
)
_USERPACK = _descriptor.Descriptor(
name='UserPack',
full_name='UserPack',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='user', full_name='UserPack.user', index=0,
number=1, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=19,
serialized_end=50,
)
_BADGE_FANCLUBTEXT = _descriptor.Descriptor(
name='FanClubText',
full_name='Badge.FanClubText',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='text', full_name='Badge.FanClubText.text', index=0,
number=1, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='color', full_name='Badge.FanClubText.color', index=1,
number=2, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='level', full_name='Badge.FanClubText.level', index=2,
number=3, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=178,
serialized_end=235,
)
_BADGE = _descriptor.Descriptor(
name='Badge',
full_name='Badge',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='url', full_name='Badge.url', index=0,
number=1, type=9, cpp_type=9, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='height', full_name='Badge.height', index=1,
number=3, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='width', full_name='Badge.width', index=2,
number=4, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='type', full_name='Badge.type', index=3,
number=6, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='clickTo', full_name='Badge.clickTo', index=4,
number=7, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='fanClubText', full_name='Badge.fanClubText', index=5,
number=8, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[_BADGE_FANCLUBTEXT, ],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=53,
serialized_end=235,
)
_FANSCLUBPACK_FANSCLUB = _descriptor.Descriptor(
name='FansClub',
full_name='FansClubPack.FansClub',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='title', full_name='FansClubPack.FansClub.title', index=0,
number=1, type=9, cpp_type=9, label=2,
has_default_value=True, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='level', full_name='FansClubPack.FansClub.level', index=1,
number=2, type=5, cpp_type=1, label=2,
has_default_value=True, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='someEnum', full_name='FansClubPack.FansClub.someEnum', index=2,
number=3, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=295,
serialized_end=358,
)
_FANSCLUBPACK = _descriptor.Descriptor(
name='FansClubPack',
full_name='FansClubPack',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='fansClub', full_name='FansClubPack.fansClub', index=0,
number=1, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[_FANSCLUBPACK_FANSCLUB, ],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=237,
serialized_end=358,
)
_USER_AVATAR = _descriptor.Descriptor(
name='Avatar',
full_name='User.Avatar',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='url', full_name='User.Avatar.url', index=0,
number=1, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='id', full_name='User.Avatar.id', index=1,
number=2, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=660,
serialized_end=693,
)
_USER_FOLLOW = _descriptor.Descriptor(
name='Follow',
full_name='User.Follow',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='following', full_name='User.Follow.following', index=0,
number=1, type=5, cpp_type=1, label=1,
has_default_value=True, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='follower', full_name='User.Follow.follower', index=1,
number=2, type=5, cpp_type=1, label=1,
has_default_value=True, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=695,
serialized_end=746,
)
_USER_PAYGRADE = _descriptor.Descriptor(
name='PayGrade',
full_name='User.PayGrade',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='current', full_name='User.PayGrade.current', index=0,
number=1, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='level', full_name='User.PayGrade.level', index=1,
number=6, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='currentLevelNeed', full_name='User.PayGrade.currentLevelNeed', index=2,
number=10, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='nextLevelNeed', full_name='User.PayGrade.nextLevelNeed', index=3,
number=11, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='content', full_name='User.PayGrade.content', index=4,
number=13, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='badge', full_name='User.PayGrade.badge', index=5,
number=19, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='toNextLevelNeed', full_name='User.PayGrade.toNextLevelNeed', index=6,
number=21, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=749,
serialized_end=905,
)
_USER_HONORLEVEL = _descriptor.Descriptor(
name='HonorLevel',
full_name='User.HonorLevel',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='badge', full_name='User.HonorLevel.badge', index=0,
number=19, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=907,
serialized_end=942,
)
_USER_NOBLE_NOBLEBOARDER = _descriptor.Descriptor(
name='NobleBoarder',
full_name='User.Noble.NobleBoarder',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='urlList', full_name='User.Noble.NobleBoarder.urlList', index=0,
number=1, type=9, cpp_type=9, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='uri', full_name='User.Noble.NobleBoarder.uri', index=1,
number=2, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='height', full_name='User.Noble.NobleBoarder.height', index=2,
number=3, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='width', full_name='User.Noble.NobleBoarder.width', index=3,
number=4, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=1014,
serialized_end=1089,
)
_USER_NOBLE = _descriptor.Descriptor(
name='Noble',
full_name='User.Noble',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='content', full_name='User.Noble.content', index=0,
number=4, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='boarder', full_name='User.Noble.boarder', index=1,
number=8, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[_USER_NOBLE_NOBLEBOARDER, ],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=945,
serialized_end=1089,
)
_USER = _descriptor.Descriptor(
name='User',
full_name='User',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='id', full_name='User.id', index=0,
number=1, type=3, cpp_type=2, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='nickname', full_name='User.nickname', index=1,
number=3, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='gender', full_name='User.gender', index=2,
number=4, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='avatarThumb', full_name='User.avatarThumb', index=3,
number=9, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='avatarMedium', full_name='User.avatarMedium', index=4,
number=10, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='avatarLarge', full_name='User.avatarLarge', index=5,
number=11, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='badge', full_name='User.badge', index=6,
number=21, type=11, cpp_type=10, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='follow', full_name='User.follow', index=7,
number=22, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='payGrade', full_name='User.payGrade', index=8,
number=23, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='fansClub', full_name='User.fansClub', index=9,
number=24, type=11, cpp_type=10, label=2,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='totalPaid', full_name='User.totalPaid', index=10,
number=34, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[_USER_AVATAR, _USER_FOLLOW, _USER_PAYGRADE, _USER_HONORLEVEL, _USER_NOBLE, ],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=361,
serialized_end=1089,
)
_USERPACK.fields_by_name['user'].message_type = _USER
_BADGE_FANCLUBTEXT.containing_type = _BADGE
_BADGE.fields_by_name['fanClubText'].message_type = _BADGE_FANCLUBTEXT
_FANSCLUBPACK_FANSCLUB.containing_type = _FANSCLUBPACK
_FANSCLUBPACK.fields_by_name['fansClub'].message_type = _FANSCLUBPACK_FANSCLUB
_USER_AVATAR.containing_type = _USER
_USER_FOLLOW.containing_type = _USER
_USER_PAYGRADE.fields_by_name['badge'].message_type = _BADGE
_USER_PAYGRADE.containing_type = _USER
_USER_HONORLEVEL.fields_by_name['badge'].message_type = _BADGE
_USER_HONORLEVEL.containing_type = _USER
_USER_NOBLE_NOBLEBOARDER.containing_type = _USER_NOBLE
_USER_NOBLE.fields_by_name['boarder'].message_type = _USER_NOBLE_NOBLEBOARDER
_USER_NOBLE.containing_type = _USER
_USER.fields_by_name['avatarThumb'].message_type = _USER_AVATAR
_USER.fields_by_name['avatarMedium'].message_type = _USER_AVATAR
_USER.fields_by_name['avatarLarge'].message_type = _USER_AVATAR
_USER.fields_by_name['badge'].message_type = _BADGE
_USER.fields_by_name['follow'].message_type = _USER_FOLLOW
_USER.fields_by_name['payGrade'].message_type = _USER_PAYGRADE
_USER.fields_by_name['fansClub'].message_type = _FANSCLUBPACK
DESCRIPTOR.message_types_by_name['UserPack'] = _USERPACK
DESCRIPTOR.message_types_by_name['Badge'] = _BADGE
DESCRIPTOR.message_types_by_name['FansClubPack'] = _FANSCLUBPACK
DESCRIPTOR.message_types_by_name['User'] = _USER
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
UserPack = _reflection.GeneratedProtocolMessageType('UserPack', (_message.Message,), {
'DESCRIPTOR' : _USERPACK,
'__module__' : 'XiguaUser_pb2'
# @@protoc_insertion_point(class_scope:UserPack)
})
_sym_db.RegisterMessage(UserPack)
Badge = _reflection.GeneratedProtocolMessageType('Badge', (_message.Message,), {
'FanClubText' : _reflection.GeneratedProtocolMessageType('FanClubText', (_message.Message,), {
'DESCRIPTOR' : _BADGE_FANCLUBTEXT,
'__module__' : 'XiguaUser_pb2'
# @@protoc_insertion_point(class_scope:Badge.FanClubText)
})
,
'DESCRIPTOR' : _BADGE,
'__module__' : 'XiguaUser_pb2'
# @@protoc_insertion_point(class_scope:Badge)
})
_sym_db.RegisterMessage(Badge)
_sym_db.RegisterMessage(Badge.FanClubText)
FansClubPack = _reflection.GeneratedProtocolMessageType('FansClubPack', (_message.Message,), {
'FansClub' : _reflection.GeneratedProtocolMessageType('FansClub', (_message.Message,), {
'DESCRIPTOR' : _FANSCLUBPACK_FANSCLUB,
'__module__' : 'XiguaUser_pb2'
# @@protoc_insertion_point(class_scope:FansClubPack.FansClub)
})
,
'DESCRIPTOR' : _FANSCLUBPACK,
'__module__' : 'XiguaUser_pb2'
# @@protoc_insertion_point(class_scope:FansClubPack)
})
_sym_db.RegisterMessage(FansClubPack)
_sym_db.RegisterMessage(FansClubPack.FansClub)
User = _reflection.GeneratedProtocolMessageType('User', (_message.Message,), {
'Avatar' : _reflection.GeneratedProtocolMessageType('Avatar', (_message.Message,), {
'DESCRIPTOR' : _USER_AVATAR,
'__module__' : 'XiguaUser_pb2'
# @@protoc_insertion_point(class_scope:User.Avatar)
})
,
'Follow' : _reflection.GeneratedProtocolMessageType('Follow', (_message.Message,), {
'DESCRIPTOR' : _USER_FOLLOW,
'__module__' : 'XiguaUser_pb2'
# @@protoc_insertion_point(class_scope:User.Follow)
})
,
'PayGrade' : _reflection.GeneratedProtocolMessageType('PayGrade', (_message.Message,), {
'DESCRIPTOR' : _USER_PAYGRADE,
'__module__' : 'XiguaUser_pb2'
# @@protoc_insertion_point(class_scope:User.PayGrade)
})
,
'HonorLevel' : _reflection.GeneratedProtocolMessageType('HonorLevel', (_message.Message,), {
'DESCRIPTOR' : _USER_HONORLEVEL,
'__module__' : 'XiguaUser_pb2'
# @@protoc_insertion_point(class_scope:User.HonorLevel)
})
,
'Noble' : _reflection.GeneratedProtocolMessageType('Noble', (_message.Message,), {
'NobleBoarder' : _reflection.GeneratedProtocolMessageType('NobleBoarder', (_message.Message,), {
'DESCRIPTOR' : _USER_NOBLE_NOBLEBOARDER,
'__module__' : 'XiguaUser_pb2'
# @@protoc_insertion_point(class_scope:User.Noble.NobleBoarder)
})
,
'DESCRIPTOR' : _USER_NOBLE,
'__module__' : 'XiguaUser_pb2'
# @@protoc_insertion_point(class_scope:User.Noble)
})
,
'DESCRIPTOR' : _USER,
'__module__' : 'XiguaUser_pb2'
# @@protoc_insertion_point(class_scope:User)
})
_sym_db.RegisterMessage(User)
_sym_db.RegisterMessage(User.Avatar)
_sym_db.RegisterMessage(User.Follow)
_sym_db.RegisterMessage(User.PayGrade)
_sym_db.RegisterMessage(User.HonorLevel)
_sym_db.RegisterMessage(User.Noble)
_sym_db.RegisterMessage(User.Noble.NobleBoarder)
# @@protoc_insertion_point(module_scope)

View File

@ -1,143 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: Xigua.proto
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='Xigua.proto',
package='',
syntax='proto2',
serialized_options=None,
serialized_pb=b'\n\x0bXigua.proto\"\x9a\x01\n\tXiguaLive\x12\x1d\n\x04\x64\x61ta\x18\x01 \x03(\x0b\x32\x0f.XiguaLive.Data\x12\x0e\n\x06\x63ursor\x18\x02 \x02(\t\x12\x16\n\x0e\x66\x65tch_interval\x18\x03 \x01(\x05\x12\x0b\n\x03now\x18\x04 \x01(\x05\x12\x14\n\x0cinternal_ext\x18\x05 \x02(\t\x1a#\n\x04\x44\x61ta\x12\x0e\n\x06method\x18\x01 \x02(\t\x12\x0b\n\x03raw\x18\x02 \x02(\x0c'
)
_XIGUALIVE_DATA = _descriptor.Descriptor(
name='Data',
full_name='XiguaLive.Data',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='method', full_name='XiguaLive.Data.method', index=0,
number=1, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='raw', full_name='XiguaLive.Data.raw', index=1,
number=2, type=12, cpp_type=9, label=2,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=135,
serialized_end=170,
)
_XIGUALIVE = _descriptor.Descriptor(
name='XiguaLive',
full_name='XiguaLive',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='data', full_name='XiguaLive.data', index=0,
number=1, type=11, cpp_type=10, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='cursor', full_name='XiguaLive.cursor', index=1,
number=2, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='fetch_interval', full_name='XiguaLive.fetch_interval', index=2,
number=3, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='now', full_name='XiguaLive.now', index=3,
number=4, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='internal_ext', full_name='XiguaLive.internal_ext', index=4,
number=5, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[_XIGUALIVE_DATA, ],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=16,
serialized_end=170,
)
_XIGUALIVE_DATA.containing_type = _XIGUALIVE
_XIGUALIVE.fields_by_name['data'].message_type = _XIGUALIVE_DATA
DESCRIPTOR.message_types_by_name['XiguaLive'] = _XIGUALIVE
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
XiguaLive = _reflection.GeneratedProtocolMessageType('XiguaLive', (_message.Message,), {
'Data' : _reflection.GeneratedProtocolMessageType('Data', (_message.Message,), {
'DESCRIPTOR' : _XIGUALIVE_DATA,
'__module__' : 'Xigua_pb2'
# @@protoc_insertion_point(class_scope:XiguaLive.Data)
})
,
'DESCRIPTOR' : _XIGUALIVE,
'__module__' : 'Xigua_pb2'
# @@protoc_insertion_point(class_scope:XiguaLive)
})
_sym_db.RegisterMessage(XiguaLive)
_sym_db.RegisterMessage(XiguaLive.Data)
# @@protoc_insertion_point(module_scope)

View File

565
api.py
View File

@ -1,520 +1,169 @@
# coding=utf-8
import sys
from Struct.MemberMsg import MemberMsg
from Struct.User import User
from Struct.Gift import Gift
from Struct.Chat import Chat
from User import User
from Gift import Gift
from Chat import Chat
import requests
import time
from datetime import datetime, timedelta
from Xigua_pb2 import XiguaLive
from XiguaMessage_pb2 import FansClubMessage, SocialMessage
DEBUG = False
# 自己抓的自己设备的参数,建议开发者自己抓一个长期使用
# 如果有大佬破解初次激活设备时的数据也行,可以自己生成一堆用
CUSTOM_INFO = {
'iid': "3993882704224472",
'device_id': "71008241150",
'cdid': "f93b3708-3fec-498f-9080-723a5679f4c0",
'openudid': "4aeb1e2b627697be",
# 'aid': "32", # 是一个不变的值
'channel': "xiaomi",
'device_brand': "Xiaomi",
'device_type': "MI+9",
'os_api': "29",
'os_version': "10",
'abi': "armeabi-v7a",
'dpi': "480",
'resolution': "1080*2217",
'rom_version': "miui_V12_V12.0.6.0.QFACNXM",
}
VERSION_INFO = {
'app_name': "video_article",
'version_code': "966",
'version_code_full': "96615",
'version_name': "9.6.6",
'ab_version': "668851,2678488,668858,2678385,668859,2678471,668856,2678470,668855,2678439,668854,994679,"
"2678460,2713070,2738381,2744004,668853,2678466,668852,2678435,2625016",
'manifest_version_code': "566",
'tma_jssdk_version': "2010000",
'oaid': "693ea85657ef38ca",
}
COMMON_GET_PARAM = (
"&iid={iid}&device_id={device_id}&ac=wifi&channel={channel}&aid=32&app_name={app_name}&version_code={version_code}&"
"version_name={version_name}&device_platform=android&ab_version={ab_version}&ssmix=a&device_type={device_type}&"
"device_brand={device_brand}&language=zh&os_api={os_api}&os_version={os_version}&openudid={openudid}&"
"manifest_version_code={manifest_version_code}&resolution={resolution}&dpi={dpi}&"
"update_version_code={version_code_full}&_rticket={{TIMESTAMP:.0f}}&"
"cdid_ts={{TIMESTAMP:.0f}}&host_abi={abi}&tma_jssdk_version={tma_jssdk_version}&"
"rom_version={rom_version}&cdid={cdid}&oaid={oaid}").format_map({**VERSION_INFO, **CUSTOM_INFO})
WEBCAST_GET_PARAMS = "webcast_sdk_version=1990&webcast_language=zh&webcast_locale=zh_CN&webcast_gps_access=1"
ROOM_ENTER_POST_PARAMS = (
"room_id={roomId}&hold_living_room=1&is_login=0&enter_from_uid_by_shared=0&video_id=0&"
"scenario=0&enter_type=click&enter_source=click_pgc_WITHIN_pgc-head_portrait&live_room_mode=0")
SEARCH_USER_API = (
"https://search5-search-lq.ixigua.com/video/app/search/live/?format=json&keyword_type=search_subtab_switch"
"&fss=search_subtab_switch&target_channel=video_search&keyword_type=search_subtab_switch&offset=0&count=10"
"&search_sug=1&forum=1&is_native_req=0&m_tab=video&pd=user&tab=user&_s_tma=SEARCH_STANDARD.list.fe_get_data"
'&_s_page_sub_route=/&_s_ec={{"filterDataType":[],"reserveFilterBar":true}}&__use_xigua_native_bridge_fetch__=1'
'&ab_param={{"is_show_filter_feature": 1, "is_hit_new_ui": 1}}'
"&search_start_time={TIMESTAMP:.0f}&from=live&en_qc=1&pd=xigua_live&ssmix=a{COMMON}&keyword={keyword}")
USER_INFO_API = "https://ib-lq.snssdk.com/video/app/user/userhome/v8/?to_user_id={userId}{COMMON}"
ROOM_INFO_API = "https://webcast5-normal-c-lq.ixigua.com/webcast/room/enter/?{WEBCAST}{COMMON}"
DANMAKU_GET_API = "https://webcast5-normal-c-lq.ixigua.com/webcast/im/fetch/?{WEBCAST}{COMMON}"
GIFT_DATA_API = ("https://webcast5-normal-c-hl.ixigua.com/webcast/gift/list/?room_id={roomId}&to_room_id={roomId}&"
"gift_scene=1&fetch_giftlist_from=2&current_network_quality_info={{}}&"
"{WEBCAST}{COMMON}")
COMMON_HEADERS = {
"x-vc-bdturing-sdk-version": "2.0.1",
"sdk-version": '2',
"passport-sdk-version": "21",
"User-Agent": "Dalvik/2.1.0 (Linux; U; Android 10; MI 9 MIUI/V12.0.6.0.QFACNXM) VideoArticle/9.6.6 "
"cronet/TTNetVersion:4b936afe 2021-01-13 QuicVersion:47946d2a 2020-10-14",
"X-SS-STUB": "74103A7F40FDC66E0675705DCA2C3A77",
"X-SS-DP": "32",
"Accept-Encoding": "gzip, deflate"
}
s = requests.Session()
class XiGuaLiveApi:
isLive: bool = False
isValidRoom: bool = False
_rawRoomInfo = {}
roomID: int = 0
roomTitle: str = ""
roomLiver: User = None
roomPopularity: int = 0
roomMember: int = 0
_cursor = ""
def __init__(self, name=None):
"""
Api类
Init Function
:param name: class:str|User: 主播名
"""
if name is None:
name = "永恒de草薙"
self.broadcaster = None
self.isValidUser = False
self.name = str(name)
if type(name) == User:
self.broadcaster = name
self.name = name.name
elif str(name).isdigit():
self.broadcaster = User()
self.isValidUser = True
self.broadcaster.ID = int(name)
else:
self.name = str(name)
self.isLive = False
self._rawRoomInfo = {}
self.roomID = 0
self.roomPopularity = 0
self.s = requests.session()
self.s.headers.update(COMMON_HEADERS)
self._updRoomAt = datetime.fromtimestamp(0)
def __init__(self, room: int):
self.room = room
self.updRoomInfo()
self._ext = ""
self._cursor = "0"
Gift.update(self.roomID)
self._enterRoom()
def _updateRoomPopularity(self, _data):
"""
更新房间人气的方法
Update Room Popularity
:param _data: Received Message
"""
if "extra" in _data:
if "member_count" in _data["extra"] and _data["extra"]["member_count"] > 0:
self.roomPopularity = _data["extra"]["member_count"]
if "data" in _data:
if "popularity" in _data["data"]:
self.roomPopularity = _data["data"]["popularity"]
def notLiveError(self):
print("主播未开播")
def getJson(self, url, **kwargs):
if "timeout" not in kwargs:
kwargs["timeout"] = 10
try:
p = self.s.get(url, **kwargs)
except Exception as e:
print("网络请求失败")
if DEBUG:
print("GET")
print("URL", url)
print("ERR ", e.__str__())
return None
try:
return p.json()
except Exception as e:
print("解析请求失败")
if DEBUG:
print("GET JSON")
print("URL", url)
print("CNT", p.text)
print("ERR ", e.__str__())
return None
def _updateRoomInfo(self, json):
if "Msg" in json:
if "member_count" in json["Msg"]:
self.roomMember = json["Msg"]["member_count"]
if "popularity" in json["Msg"]:
self.roomPopularity = json["Msg"]["popularity"]
def postJson(self, url, data, **kwargs):
if "timeout" not in kwargs:
kwargs["timeout"] = 10
try:
p = self.s.post(url, data=data, **kwargs)
except Exception as e:
print("网络请求失败")
if DEBUG:
print("POST")
print("URL", url)
print("DATA", data)
print("ERR ", e.__str__())
return None
try:
return p.json()
except Exception as e:
print("解析请求失败")
if DEBUG:
print("POST JSON")
print("URL", url)
print("DATA", data)
print("CNT", p.text)
print("HDR", p.headers)
print("ERR ", e.__str__())
return None
@staticmethod
def apiChangedError(msg: str, *args):
"""
API发生更改时的提示
Warning while Detected Api has Changed
:param msg: 提示信息
:param args: DEBUG模式下显示更多信息
"""
def apiChangedError(self, msg: str, *args):
print(msg)
if DEBUG:
print(*args)
def onPresent(self, gift: Gift):
"""
礼物连击中的消息
Message On Sending Presents
:param gift: Struct of Gift Message
"""
print("礼物连击 :", gift)
print("礼物连击:", gift)
def onPresentEnd(self, gift: Gift):
"""
礼物送完了的提示信息
Message On Finished Send Present
:param gift: Struct of Gift Message
"""
print("感谢", gift)
def onAd(self, i):
"""
全局广播
All Channel Broadcasting Message( Just An Ad )
:param i: JSON DATA if you wanna using it
"""
# print(i)
pass
def onChat(self, chat: Chat):
"""
聊天信息
On Chatting
:param chat: Struct of Chat Message
"""
if not chat.isFiltered:
print(chat)
def onEnter(self, msg: MemberMsg):
"""
进入房间消息
On Entering Room
:param msg: Struct of Member Message
"""
print("提示 :", msg)
def onEnter(self, user: User, content: str == ""):
if content == "":
print("消息:", user, "进入直播间")
else:
print("消息:", content.format(user))
def onSubscribe(self, user: User):
"""
关注主播时的消息
On Subscribe
:param user: Struct of User Message
"""
print("消息 :", user, "关注了主播")
print("消息:", user, "关注了主播")
def onJoin(self, user: User):
"""
加入粉丝团消息
:param user:
"""
print("欢迎", user, "加入了粉丝团")
print("感谢", user, "加入了粉丝团")
def onMessage(self, msg: str):
"""
系统消息
:param msg:
"""
print("消息 :", msg)
print("消息:", msg)
def onLike(self, user: User):
"""
点击喜欢的消息
On Like
:param user:
"""
print("用户", user, "点了喜欢")
def onLeave(self, json: any):
"""
下播消息
On Liver Leave
:param json:
"""
print("消息 :", "主播离开了")
self.updRoomInfo()
print("消息:", "主播离开一小会")
def _checkUsernameIsMatched(self, compare=None):
"""
验证主播名字是自己想要的那个
Check name matched
:return: bool: 是否匹配
"""
if compare is None:
compare = self.broadcaster
if self.name is None or compare is None:
return False
return self.name == compare.__str__() or compare.__repr__() in self.name or self.name in compare.__repr__()
def _enterRoom(self):
if not self.isValidRoom:
return
p = s.post("https://live.ixigua.com/api/room/enter/{roomID}".format(roomID=self.roomID))
def _forceSearchUser(self):
"""
搜索主播名
:return:
"""
_formatData = {"TIMESTAMP": time.time() * 1000, "keyword": self.name}
_COMMON = COMMON_GET_PARAM.format_map(_formatData)
_formatData['COMMON'] = _COMMON
_url = SEARCH_USER_API.format_map(_formatData)
d = self.getJson(_url)
if d is None:
print("搜索接口请求失败")
return False
self.broadcaster = None
self.isValidUser = False
self.isLive = False
if "data" in d and d["data"] is not None:
for i in d["data"]:
if self.broadcaster is not None:
break
if i["card_type"] != 3:
continue
if "search_data" not in i or len(i["search_data"]) == 0:
break
for _j in i["search_data"]:
if "room" in _j:
_user = User(_j["room"])
self.roomID = _j["room"]["room_id"]
self.isLive = _j["room"]["is_living"]
if self._checkUsernameIsMatched(_user):
self.isValidUser = True
self.broadcaster = _user
break
self._updRoomAt = datetime.now()
return self._updateUserInfo()
def _updateUserInfo(self):
"""
获取用户信息
:return:
"""
if self.broadcaster is None:
self.isValidUser = False
return False
self.isLive = False
_formatData = {"TIMESTAMP": time.time() * 1000, "userId": self.broadcaster.ID}
_COMMON = COMMON_GET_PARAM.format_map(_formatData)
_formatData['COMMON'] = _COMMON
_url = USER_INFO_API.format_map(_formatData)
d = self.getJson(_url)
if d is None:
print("获取用户信息失败")
return False
self.isValidUser = d["status"] == 0
_d = d.get('data', {})
if "user_home_info" not in _d and _d['user_home_info']['user_info'] is None:
self.apiChangedError("Api发生改变请及时联系我", d)
return False
self._updRoomAt = datetime.now()
self.broadcaster = User(_d['user_home_info'])
if not self._checkUsernameIsMatched():
self.isLive = False
return False
self.isLive = 'user_live_info_list' in _d
if self.isLive and len(_d['user_live_info_list']) != 0:
# 既然有长度,默认个0应该没事
self._rawRoomInfo = _d['user_live_info_list'][0]['live_info']
else:
self.isLive = False
if self.isLive:
self.roomID = self._rawRoomInfo['room_id']
return self._getRoomInfo(True)
return self.isLive
def _getRoomInfo(self, force=False):
if self.roomID == 0 or not self.roomID:
self.isLive = False
return False
if (self._updRoomAt + timedelta(minutes=3) > datetime.now()) and not force:
return self.isLive
_formatData = {"TIMESTAMP": time.time() * 1000}
_COMMON = COMMON_GET_PARAM.format_map(_formatData)
_formatData['COMMON'] = _COMMON
_formatData['WEBCAST'] = WEBCAST_GET_PARAMS
_url = ROOM_INFO_API.format_map(_formatData)
_postData = ROOM_ENTER_POST_PARAMS.format_map({'roomId': self.roomID})
_headers = {"response-format": "json",
'Connection': "keep-alive",
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Content-Length': str(len(_postData)),
**COMMON_HEADERS,
}
d = self.postJson(_url, _postData, headers=_headers)
self.isLive = False
if d is None:
print("获取房间信息接口请求失败")
return False
if d["status_code"] != 0:
print("接口提示:【{}".format(d["data"]["message"]))
return False
def updRoomInfo(self):
p = s.get("https://live.ixigua.com/api/room/{room}".format(room=self.room))
d = p.json()
if "data" not in d:
self.apiChangedError("无法获取RoomID请与我联系")
return
self.isValidRoom = True
self._rawRoomInfo = d["data"]
self.isLive = self._rawRoomInfo["status"] == 2
self._updRoomAt = datetime.now()
self._updateRoomPopularity(d)
return self.isLive
def updRoomInfo(self, force=False):
"""
更新房间信息
:return:
"""
if not force and (self._updRoomAt + timedelta(minutes=2) > datetime.now()):
return self.isLive
if not self.isValidUser:
return self._forceSearchUser()
elif not self.isLive:
return self._updateUserInfo()
self.roomLiver = User(d)
self.roomTitle = self._rawRoomInfo["Title"]
self.roomPopularity = self._rawRoomInfo["Extra2"]["Popularity"]
if "Id" in d["data"]:
self.roomID = d["data"]["Id"]
else:
return self._getRoomInfo(force)
def updGiftInfo(self):
self.updRoomInfo()
_formatData = {"TIMESTAMP": time.time() * 1000, "roomId": self.roomID}
_COMMON = COMMON_GET_PARAM.format_map(_formatData)
_formatData['COMMON'] = _COMMON
_formatData['WEBCAST'] = WEBCAST_GET_PARAMS
_url = GIFT_DATA_API.format_map(_formatData)
d = self.getJson(_url)
if d is None or d["status_code"] != 0:
return "异常"
elif 'pages' in d["data"]:
for _page in d["data"]['pages']:
if 'gifts' in _page:
for _gift in _page['gifts']:
Gift.addGift(_gift)
return len(Gift.giftList)
self.apiChangedError("无法获取RoomID请与我联系")
if "FinishTime" in d["data"]:
self.isLive = False
self.notLiveError()
else:
self.isLive = True
def getDanmaku(self):
"""
获取弹幕
"""
self.updRoomInfo()
if not self.isLive:
if not self.isValidRoom:
return
_formatData = {"TIMESTAMP": time.time() * 1000, "roomId": self.roomID}
_COMMON = COMMON_GET_PARAM.format_map(_formatData)
_formatData['COMMON'] = _COMMON
_formatData['WEBCAST'] = WEBCAST_GET_PARAMS
_url = DANMAKU_GET_API.format_map(_formatData)
p = self.s.post(_url, data="room_id={roomId}&fetch_rule=0&cursor={cursor}&"
"resp_content_type=protobuf&live_id=3&user_id=0&identity=audience&"
"last_rtt=85&internal_ext={ext}"
.format_map({"roomId":self.roomID, "cursor": self._cursor, "ext": self._ext}),
headers={"Content-Type": "application/x-www-form-urlencoded"})
if p.status_code != 200:
p = s.get("https://live.ixigua.com/api/msg/list/{roomID}?AnchorID={room}&Cursor={cursor}".format(
roomID=self.roomID,
room=self.room,
cursor=self._cursor
))
d = p.json()
if "data" not in d:
self.apiChangedError("数据结构改变,请与我联系", d)
return
if "Extra" not in d["data"]:
self.apiChangedError("数据结构改变,请与我联系", d)
return
if "Cursor" not in d["data"]["Extra"]:
self.apiChangedError("数据结构改变,请与我联系", d)
return
data = XiguaLive()
data.ParseFromString(p.content)
self._cursor = data.cursor
self._ext = data.internal_ext
for _each in data.data:
if _each.method == "WebcastGiftMessage":
_gift = Gift(_each.raw)
if _gift.isAnimate() or _gift.isFinished:
self.onPresentEnd(_gift)
else:
self.onPresent(_gift)
elif _each.method == "WebcastChatMessage":
_chat = Chat(_each.raw)
self.onChat(_chat)
elif _each.method == "WebcastControlMessage":
# 下播的时候会有个这个
self.onLeave(None)
elif _each.method == "WebcastSocialMessage":
_socialMessage = SocialMessage()
_socialMessage.ParseFromString(_each.raw)
_user = User(_socialMessage.user)
self.onSubscribe(_user)
elif _each.method == "WebcastFansclubMessage":
_fansClubMessage = FansClubMessage()
_fansClubMessage.ParseFromString(_each.raw)
# 升级是1加入是2
if _fansClubMessage.type == 2:
_user = User(_fansClubMessage.user)
self.onJoin(_user)
else:
self.onMessage(_fansClubMessage.content)
self._cursor = d["data"]["Extra"]["Cursor"]
if "LiveMsgs" not in d["data"]:
return
for i in d['data']['LiveMsgs']:
if i['Method'] == "VideoLivePresentMessage":
self.onPresent(Gift(i))
elif i['Method'] == "VideoLivePresentEndTipMessage":
self.onPresentEnd(Gift(i))
elif i['Method'] == "VideoLiveRoomAdMessage":
self.onAd(i)
elif i['Method'] == "VideoLiveChatMessage":
self.onChat(Chat(i))
elif i['Method'] == "VideoLiveMemberMessage":
self._updateRoomInfo(i)
self.onEnter(User(i), i["Msg"]["content"])
elif i['Method'] == "VideoLiveSocialMessage":
self.onSubscribe(User(i))
elif i['Method'] == "VideoLiveJoinDiscipulusMessage":
self.onJoin(User(i))
elif i['Method'] == "VideoLiveControlMessage":
print("消息:", "主播离开一小会")
elif i['Method'] == "VideoLiveDiggMessage":
self.onLike(User(i))
else:
pass
@property
def updateAt(self):
return self._updRoomAt
def public_hello():
print("西瓜直播弹幕助手 by JerryYan")
print("接口版本:{version_name}({version_code_full})".format_map(VERSION_INFO))
if __name__ == "__main__":
name = "永恒de草薙"
if len(sys.argv) > 2:
if sys.argv[-1] == "d":
DEBUG = True
name = sys.argv[1]
public_hello()
print("搜索【", name, "", end="\t", flush=True)
api = XiGuaLiveApi(name)
if not api.isValidUser:
input("用户不存在")
room = 97621754276 # 永恒
# room = 75366565294
# room = 83940182312 #Dae
print("西瓜直播弹幕助手 by JerryYan")
api = XiGuaLiveApi(room)
print("进入", api.roomLiver, "的直播间")
if not api.isValidRoom:
input("房间不存在")
sys.exit()
print("OK")
print(api.broadcaster.__repr__())
print("更新房间信息,请稍后", end="\t", flush=True)
if api.updRoomInfo(True):
print("OK")
else:
print("FAIL")
print("更新房间礼物信息", end="\t", flush=True)
__res = api.updGiftInfo()
if __res < 0:
print("FAIL")
else:
print('OK\n礼物种数:', __res)
print("=" * 30)
while True:
if api.isLive:
try:
api.getDanmaku()
except Exception as e:
print(e)
time.sleep(1)
except requests.exceptions.BaseHTTPError:
print("网络错误,请确认网络")
time.sleep(5)
# except Exception as e:
# print(e)
else:
print("主播未开播等待1分钟后重试")
time.sleep(60)
api.updRoomInfo(True)
api.updRoomInfo()

View File

@ -1,121 +0,0 @@
from bilibiliuploader import core, VideoPart
class Bilibili:
def __init__(self):
self.access_token = ""
self.session_id = ""
self.user_id = ""
self.parts = []
def login(self):
from Common import appendOperation
with open("access_token", "r") as f:
self.access_token = f.read(64).strip()
self.session_id, self.user_id, expires = core.login_by_access_token(self.access_token)
appendOperation("B站登录UID【{}】,过期时间【{}".format(self.user_id, expires))
def upload(self,
parts,
title,
tid,
tag,
desc,
source='',
cover='',
no_reprint=1,
):
"""
:param parts: e.g. VideoPart('part path', 'part title', 'part desc'), or [VideoPart(...), VideoPart(...)]
:type parts: VideoPart or list<VideoPart>
:param title: video's title
:type title: str
:param tid: video type, see: https://member.bilibili.com/x/web/archive/pre
or https://github.com/uupers/BiliSpider/wiki/%E8%A7%86%E9%A2%91%E5%88%86%E5%8C%BA%E5%AF%B9%E5%BA%94%E8%A1%A8
:type tid: int
:param tag: video's tag
:type tag: list<str>
:param desc: video's description
:type desc: str
:param source: (optional) 转载地址
:type source: str
:param cover: (optional) cover's URL, use method *cover_up* to get
:type cover: str
:param no_reprint: (optional) 0=可以转载, 1=禁止转载(default)
:type no_reprint: int
"""
self.preUpload(parts)
self.finishUpload(title, tid, tag, desc, source, cover, no_reprint)
self.clear()
def preUpload(self, parts, max_retry=5):
"""
:param max_retry:
:param parts: e.g. VideoPart('part path', 'part title', 'part desc'), or [VideoPart(...), VideoPart(...)]
:type parts: VideoPart or list<VideoPart>
"""
from Common import appendUploadStatus, modifyLastUploadStatus, appendError
if not isinstance(parts, list):
parts = [parts]
def log_status(video_part: VideoPart, chunks_index: int, chunks_num: int):
modifyLastUploadStatus("Uploading >{}< @ {:.2f}%".format(video_part.path, 100.0 * chunks_index / chunks_num))
for part in parts:
appendUploadStatus("Start Uploading >{}<".format(part.path))
status = core.upload_video_part(self.access_token, self.session_id, self.user_id, part, max_retry, cb=log_status)
if status:
# 上传完毕
modifyLastUploadStatus("Upload >{}< Finished{}".format(part.path, part.server_file_name))
self.parts.append(part)
else:
modifyLastUploadStatus("Upload >{}< Failed".format(part.path))
def finishUpload(self,
title,
tid,
tag,
desc,
source='',
cover='',
no_reprint=1,
):
"""
:param title: video's title
:type title: str
:param tid: video type, see: https://member.bilibili.com/x/web/archive/pre
or https://github.com/uupers/BiliSpider/wiki/%E8%A7%86%E9%A2%91%E5%88%86%E5%8C%BA%E5%AF%B9%E5%BA%94%E8%A1%A8
:type tid: int
:param tag: video's tag
:type tag: list<str>
:param desc: video's description
:type desc: str
:param source: (optional) 转载地址
:type source: str
:param cover: (optional) cover's URL, use method *cover_up* to get
:type cover: str
:param no_reprint: (optional) 0=可以转载, 1=禁止转载(default)
:type no_reprint: int
:param copyright: (optional) 0=转载的, 1=自制的(default)
:type copyright: int
"""
from Common import appendUploadStatus, modifyLastUploadStatus, appendError
if len(self.parts) == 0:
return
appendUploadStatus("[{}]投稿中,请稍后".format(title))
copyright = 2 if source else 1
try:
avid, bvid = core.upload(self.access_token, self.session_id, self.user_id, self.parts, copyright,
title=title, tid=tid, tag=','.join(tag), desc=desc, source=source, cover=cover, no_reprint=no_reprint)
modifyLastUploadStatus("[{}]投稿成功AVID【{}BVID【{}".format(title, avid, bvid))
self.clear()
except Exception as e:
modifyLastUploadStatus("[{}]投稿失败".format(title))
appendError(e)
def reloadFromPrevious(self):
...
def clear(self):
self.parts = []

View File

@ -1,4 +0,0 @@
修改自
https://github.com/FortuneDayssss/BilibiliUploader/
LICENSEGPL

View File

@ -1,4 +0,0 @@
from .bilibiliuploader import BilibiliUploader
from .core import VideoPart
__version__ = '0.0.6'

View File

@ -1,118 +0,0 @@
import bilibiliuploader.core as core
from bilibiliuploader.util import cipher
import json
class BilibiliUploader():
def __init__(self):
self.access_token = None
self.refresh_token = None
self.sid = None
self.mid = None
def login(self, username, password):
code, self.access_token, self.refresh_token, self.sid, self.mid, _ = core.login(username, password)
if code != 0: # success
print("login fail, error code = {}".format(code))
def login_by_access_token(self, access_token, refresh_token=None):
self.access_token = access_token
self.refresh_token = refresh_token
self.sid, self.mid, _ = core.login_by_access_token(access_token)
def login_by_access_token_file(self, file_name):
with open(file_name, "r") as f:
login_data = json.loads(f.read())
self.access_token = login_data["access_token"]
self.refresh_token = login_data["refresh_token"]
self.sid, self.mid, _ = core.login_by_access_token(self.access_token)
def save_login_data(self, file_name=None):
login_data = json.dumps(
{
"access_token": self.access_token,
"refresh_token": self.refresh_token
}
)
try:
with open(file_name, "w+") as f:
f.write(login_data)
finally:
return login_data
def upload(self,
parts,
copyright: int,
title: str,
tid: int,
tag: str,
desc: str,
source: str = '',
cover: str = '',
no_reprint: int = 0,
open_elec: int = 1,
max_retry: int = 5,
thread_pool_workers: int = 1):
return core.upload(self.access_token,
self.sid,
self.mid,
parts,
copyright,
title,
tid,
tag,
desc,
source,
cover,
no_reprint,
open_elec,
max_retry,
thread_pool_workers)
def edit(self,
avid=None,
bvid=None,
parts=None,
insert_index=None,
copyright=None,
title=None,
tid=None,
tag=None,
desc=None,
source=None,
cover=None,
no_reprint=None,
open_elec=None,
max_retry: int = 5,
thread_pool_workers: int = 1):
if not avid and not bvid:
print("please provide avid or bvid")
return None, None
if not avid:
avid = cipher.bv2av(bvid)
if not isinstance(parts, list):
parts = [parts]
if type(avid) is str:
avid = int(avid)
core.edit_videos(
self.access_token,
self.sid,
self.mid,
avid,
bvid,
parts,
insert_index,
copyright,
title,
tid,
tag,
desc,
source,
cover,
no_reprint,
open_elec,
max_retry,
thread_pool_workers
)

View File

@ -1,790 +0,0 @@
import requests
from datetime import datetime
from bilibiliuploader.util import cipher as cipher
from urllib import parse
import os
import math
import hashlib
from bilibiliuploader.util.retry import Retry
from concurrent.futures import ThreadPoolExecutor, as_completed
import base64
# From PC ugc_assisstant
# APPKEY = 'aae92bc66f3edfab'
# APPSECRET = 'af125a0d5279fd576c1b4418a3e8276d'
APPKEY = '1d8b6e7d45233436'
APPSECRET = '560c52ccd288fed045859ed18bffd973'
LOGIN_APPKEY = '783bbb7264451d82'
# upload chunk size = 2MB
CHUNK_SIZE = 2 * 1024 * 1024
# captcha
CAPTCHA_RECOGNIZE_URL = "NOT SUPPORT"
class VideoPart:
"""
Video Part of a post.
每个对象代表一个分P
Attributes:
path: file path in local file system.
title: title of the video part.
desc: description of the video part.
server_file_name: file name in bilibili server. generated by pre-upload API.
"""
def __init__(self, path, title='', desc='', server_file_name=None):
self.path = path
self.title = title
self.desc = desc
self.server_file_name = server_file_name
def __repr__(self):
return '<{clazz}, path: {path}, title: {title}, desc: {desc}, server_file_name:{server_file_name}>' \
.format(clazz=self.__class__.__name__,
path=self.path,
title=self.title,
desc=self.desc,
server_file_name=self.server_file_name)
def get_key_old(sid=None, jsessionid=None):
"""
get public key, hash and session id for login.
Args:
sid: session id. only for captcha login.
jsessionid: j-session id. only for captcha login.
Returns:
hash: salt for password encryption.
pubkey: rsa public key for password encryption.
sid: session id.
"""
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': "application/json, text/javascript, */*; q=0.01"
}
post_data = {
'appkey': APPKEY,
'platform': "pc",
'ts': str(int(datetime.now().timestamp()))
}
post_data['sign'] = cipher.sign_dict(post_data, APPSECRET)
cookie = {}
if sid:
cookie['sid'] = sid
if jsessionid:
cookie['JSESSIONID'] = jsessionid
r = requests.post(
# "https://passport.bilibili.com/api/oauth2/getKey",
"https://passport.bilibili.com/x/passport-login/web/key",
headers=headers,
data=post_data,
cookies=cookie
)
print(r.content.decode())
r_data = r.json()['data']
if sid:
return r_data['hash'], r_data['key'], sid
return r_data['hash'], r_data['key'], r.cookies['sid']
def get_key():
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': "application/json, text/javascript, */*; q=0.01"
}
params_data = {
'appkey': LOGIN_APPKEY,
# 'ts': str(int(datetime.now().timestamp()))
}
params_data['sign'] = cipher.login_sign_dict_bin(params_data)
r = requests.get(
"https://passport.bilibili.com/x/passport-login/web/key",
headers=headers,
params=params_data
)
r_data = r.json()['data']
return r_data['hash'], r_data['key'], ''
def get_capcha(sid):
headers = {
'User-Agent': '',
'Accept-Encoding': 'gzip,deflate',
}
params = {
'appkey': APPKEY,
'platform': 'pc',
'ts': str(int(datetime.now().timestamp()))
}
params['sign'] = cipher.sign_dict(params, APPSECRET)
r = requests.get(
"https://passport.bilibili.com/captcha",
headers=headers,
params=params,
cookies={
'sid': sid
}
)
print(r.status_code)
capcha_data = r.content
return r.cookies['JSESSIONID'], capcha_data
def recognize_captcha(img: bytes):
img_base64 = str(base64.b64encode(img), encoding='utf-8')
r = requests.post(
url=CAPTCHA_RECOGNIZE_URL,
data={'image': img_base64}
)
return r.content.decode()
def login(username, password):
"""
bilibili login.
Args:
username: plain text username for bilibili.
password: plain text password for bilibili.
Returns:
code: login response code (0: success, -105: captcha error, ...).
access_token: token for further operation.
refresh_token: token for refresh access_token.
sid: session id.
mid: member id.
expires_in: access token expire time (30 days)
"""
hash, pubkey, sid = get_key()
encrypted_password = cipher.encrypt_login_password(password, hash, pubkey)
url_encoded_username = parse.quote_plus(username)
url_encoded_password = parse.quote_plus(encrypted_password)
post_data = {
'appkey': LOGIN_APPKEY,
'password': url_encoded_password,
'ts': str(int(datetime.now().timestamp())),
'username': url_encoded_username
}
post_data['sign'] = cipher.login_sign_dict_bin(post_data)
# avoid multiple url parse
post_data['username'] = username
post_data['password'] = encrypted_password
headers = {
'Connection': 'keep-alive',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'User-Agent': '',
'Accept-Encoding': 'gzip,deflate',
}
r = requests.post(
# "https://passport.bilibili.com/api/v3/oauth2/login",
"https://passport.bilibili.com/x/passport-login/oauth2/login",
headers=headers,
data=post_data,
)
response = r.json()
response_code = response['code']
if response_code == 0:
login_data = response['data']['token_info']
return response_code, login_data['access_token'], login_data['refresh_token'], sid, login_data['mid'], \
login_data["expires_in"]
elif response_code == -105: # captcha error, retry=5
retry_cnt = 5
while response_code == -105 and retry_cnt > 0:
response_code, access_token, refresh_token, sid, mid, expire_in = login_captcha(username, password, sid)
if response_code == 0:
return response_code, access_token, refresh_token, sid, mid, expire_in
retry_cnt -= 1
# other error code
return response_code, None, None, sid, None, None
def login_captcha(username, password, sid):
"""
bilibili login with captcha.
depend on captcha recognize service, please do not use this as first choice.
Args:
username: plain text username for bilibili.
password: plain text password for bilibili.
sid: session id
Returns:
code: login response code (0: success, -105: captcha error, ...).
access_token: token for further operation.
refresh_token: token for refresh access_token.
sid: session id.
mid: member id.
expires_in: access token expire time (30 days)
"""
jsessionid, captcha_img = get_capcha(sid)
captcha_str = recognize_captcha(captcha_img)
hash, pubkey, sid = get_key(sid, jsessionid)
encrypted_password = cipher.encrypt_login_password(password, hash, pubkey)
url_encoded_username = parse.quote_plus(username)
url_encoded_password = parse.quote_plus(encrypted_password)
post_data = {
'appkey': APPKEY,
'captcha': captcha_str,
'password': url_encoded_password,
'platform': "pc",
'ts': str(int(datetime.now().timestamp())),
'username': url_encoded_username
}
post_data['sign'] = cipher.sign_dict(post_data, APPSECRET)
# avoid multiple url parse
post_data['username'] = username
post_data['password'] = encrypted_password
post_data['captcha'] = captcha_str
headers = {
'Connection': 'keep-alive',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'User-Agent': '',
'Accept-Encoding': 'gzip,deflate',
}
r = requests.post(
"https://passport.bilibili.com/api/oauth2/login",
headers=headers,
data=post_data,
cookies={
'JSESSIONID': jsessionid,
'sid': sid
}
)
response = r.json()
if response['code'] == 0:
login_data = response['data']
return response['code'], login_data['access_token'], login_data['refresh_token'], sid, login_data['mid'], \
login_data["expires_in"]
else:
return response['code'], None, None, sid, None, None
def login_by_access_token(access_token):
"""
bilibili access token login.
Args:
access_token: Bilibili access token got by previous username/password login.
Returns:
sid: session id.
mid: member id.
expires_in: access token expire time
"""
headers = {
'Connection': 'keep-alive',
'Accept-Encoding': 'gzip,deflate',
'Host': 'passport.bilibili.com',
'User-Agent': '',
}
login_params = {
'appkey': APPKEY,
'access_token': access_token,
'platform': "pc",
'ts': str(int(datetime.now().timestamp())),
}
login_params['sign'] = cipher.sign_dict(login_params, APPSECRET)
r = requests.get(
url="https://passport.bilibili.com/api/oauth2/info",
headers=headers,
params=login_params
)
login_data = r.json()['data']
return r.cookies['sid'], login_data['mid'], login_data["expires_in"]
def upload_cover(access_token, sid, cover_file_path):
with open(cover_file_path, "rb") as f:
cover_pic = f.read()
headers = {
'Connection': 'keep-alive',
'Host': 'member.bilibili.com',
'Accept-Encoding': 'gzip,deflate',
'User-Agent': '',
}
params = {
"access_key": access_token,
}
params["sign"] = cipher.sign_dict(params, APPSECRET)
files = {
'file': ("cover.png", cover_pic, "Content-Type: image/png"),
}
r = requests.post(
"http://member.bilibili.com/x/vu/client/cover/up",
headers=headers,
params=params,
files=files,
cookies={
'sid': sid
},
verify=False,
)
return r.json()["data"]["url"]
def upload_chunk(upload_url, server_file_name, local_file_name, chunk_data, chunk_size, chunk_id, chunk_total_num):
"""
upload video chunk.
Args:
upload_url: upload url by pre_upload api.
server_file_name: file name on server by pre_upload api.
local_file_name: video file name in local fs.
chunk_data: binary data of video chunk.
chunk_size: default of ugc_assisstant is 2M.
chunk_id: chunk number.
chunk_total_num: total chunk number.
Returns:
True: upload chunk success.
False: upload chunk fail.
"""
print("chunk{}/{}".format(chunk_id, chunk_total_num))
print("filename: {}".format(local_file_name))
files = {
'version': (None, '2.0.0.1054'),
'filesize': (None, chunk_size),
'chunk': (None, chunk_id),
'chunks': (None, chunk_total_num),
'md5': (None, cipher.md5_bytes(chunk_data)),
'file': (local_file_name, chunk_data, 'application/octet-stream')
}
r = requests.post(
url=upload_url,
files=files,
cookies={
'PHPSESSID': server_file_name
},
)
print(r.status_code)
print(r.content)
if r.status_code == 200 and r.json()['OK'] == 1:
return True
else:
return False
def upload_video_part(access_token, sid, mid, video_part: VideoPart, max_retry=5, cb=None):
"""
upload a video file.
Args:
access_token: access token generated by login api.
sid: session id.
mid: member id.
video_part: local video file data.
max_retry: max retry number for each chunk.
cb: 回调
Returns:
status: success or fail.
server_file_name: server file name by pre_upload api.
"""
if cb is None:
cb = lambda f, c, t: None
if not isinstance(video_part, VideoPart):
return False
if video_part.server_file_name is not None:
return True
headers = {
'Connection': 'keep-alive',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'User-Agent': '',
'Accept-Encoding': 'gzip,deflate',
}
r = requests.get(
"http://member.bilibili.com/preupload?access_key={}&mid={}&profile=ugcfr%2Fpc3".format(access_token, mid),
headers=headers,
cookies={
'sid': sid
},
verify=False,
)
pre_upload_data = r.json()
upload_url = pre_upload_data['url']
complete_upload_url = pre_upload_data['complete']
server_file_name = pre_upload_data['filename']
local_file_name = video_part.path
file_size = os.path.getsize(local_file_name)
chunk_total_num = int(math.ceil(file_size / CHUNK_SIZE))
file_hash = hashlib.md5()
with open(local_file_name, 'rb') as f:
for chunk_id in range(0, chunk_total_num):
chunk_data = f.read(CHUNK_SIZE)
cb(video_part, chunk_id, chunk_total_num)
status = Retry(max_retry=max_retry, success_return_value=True).run(
upload_chunk,
upload_url,
server_file_name,
os.path.basename(local_file_name),
chunk_data,
CHUNK_SIZE,
chunk_id,
chunk_total_num
)
if not status:
return False
file_hash.update(chunk_data)
print(file_hash.hexdigest())
# complete upload
post_data = {
'chunks': chunk_total_num,
'filesize': file_size,
'md5': file_hash.hexdigest(),
'name': os.path.basename(local_file_name),
'version': '2.0.0.1054',
}
r = requests.post(
url=complete_upload_url,
data=post_data,
headers=headers,
)
print(r.status_code)
print(r.content)
video_part.server_file_name = server_file_name
return True
def upload(access_token,
sid,
mid,
parts,
copyright: int,
title: str,
tid: int,
tag: str,
desc: str,
source: str = '',
cover: str = '',
no_reprint: int = 0,
open_elec: int = 1,
max_retry: int = 5,
thread_pool_workers: int = 1):
"""
upload video.
Args:
access_token: oauth2 access token.
sid: session id.
mid: member id.
parts: VideoPart list.
copyright: 原创/转载.
title: 投稿标题.
tid: 分区id.
tag: 标签.
desc: 投稿简介.
source: 转载地址.
cover: 封面图片文件路径.
no_reprint: 可否转载.
open_elec: 充电.
max_retry: max retry time for each chunk.
thread_pool_workers: max upload threads.
Returns:
(aid, bvid)
aid: av号
bvid: bv号
"""
if not isinstance(parts, list):
parts = [parts]
status = True
with ThreadPoolExecutor(max_workers=thread_pool_workers) as tpe:
t_list = []
for video_part in parts:
print("upload {} added in pool".format(video_part.title))
t_obj = tpe.submit(upload_video_part, access_token, sid, mid, video_part, max_retry)
t_obj.video_part = video_part
t_list.append(t_obj)
for t_obj in as_completed(t_list):
status = status and t_obj.result()
print("video part {} finished, status: {}".format(t_obj.video_part.title, t_obj.result()))
if not status:
print("upload failed")
return None, None
# cover
if os.path.isfile(cover):
try:
cover = upload_cover(access_token, sid, cover)
except:
cover = ''
else:
cover = ''
# submit
headers = {
'Connection': 'keep-alive',
'Content-Type': 'application/json',
'User-Agent': '',
}
post_data = {
'build': 1054,
'copyright': copyright,
'cover': cover,
'desc': desc,
'no_reprint': no_reprint,
'open_elec': open_elec,
'source': source,
'tag': tag,
'tid': tid,
'title': title,
'videos': []
}
for video_part in parts:
post_data['videos'].append({
"desc": video_part.desc,
"filename": video_part.server_file_name,
"title": video_part.title
})
params = {
'access_key': access_token,
}
params['sign'] = cipher.sign_dict(params, APPSECRET)
r = requests.post(
url="http://member.bilibili.com/x/vu/client/add",
params=params,
headers=headers,
verify=False,
cookies={
'sid': sid
},
json=post_data,
)
print("submit")
print(r.status_code)
print(r.content.decode())
data = r.json()["data"]
return data["aid"], data["bvid"]
def get_post_data(access_token, sid, avid):
headers = {
'Connection': 'keep-alive',
'Host': 'member.bilibili.com',
'Accept-Encoding': 'gzip,deflate',
'User-Agent': '',
}
params = {
"access_key": access_token,
"aid": avid,
"build": "1054"
}
params["sign"] = cipher.sign_dict(params, APPSECRET)
r = requests.get(
url="http://member.bilibili.com/x/client/archive/view",
headers=headers,
params=params,
cookies={
'sid': sid
}
)
return r.json()["data"]
def edit_videos(
access_token,
sid,
mid,
avid=None,
bvid=None,
parts=None,
insert_index=None,
copyright=None,
title=None,
tid=None,
tag=None,
desc=None,
source=None,
cover=None,
no_reprint=None,
open_elec=None,
max_retry: int = 5,
thread_pool_workers: int = 1):
"""
insert videos into existed post.
Args:
access_token: oauth2 access token.
sid: session id.
mid: member id.
avid: av number,
bvid: bv string,
parts: VideoPart list.
insert_index: new video index.
copyright: 原创/转载.
title: 投稿标题.
tid: 分区id.
tag: 标签.
desc: 投稿简介.
source: 转载地址.
cover: cover url.
no_reprint: 可否转载.
open_elec: 充电.
max_retry: max retry time for each chunk.
thread_pool_workers: max upload threads.
Returns:
(aid, bvid)
aid: av号
bvid: bv号
"""
if not avid and not bvid:
print("please provide avid or bvid")
return None, None
if not avid:
avid = cipher.bv2av(bvid)
if not isinstance(parts, list):
parts = [parts]
if type(avid) is str:
avid = int(avid)
post_video_data = get_post_data(access_token, sid, avid)
status = True
with ThreadPoolExecutor(max_workers=thread_pool_workers) as tpe:
t_list = []
for video_part in parts:
print("upload {} added in pool".format(video_part.title))
t_obj = tpe.submit(upload_video_part, access_token, sid, mid, video_part, max_retry)
t_obj.video_part = video_part
t_list.append(t_obj)
for t_obj in as_completed(t_list):
status = status and t_obj.result()
print("video part {} finished, status: {}".format(t_obj.video_part.title, t_obj.result()))
if not status:
print("upload failed")
return None, None
headers = {
'Connection': 'keep-alive',
'Content-Type': 'application/json',
'User-Agent': '',
}
submit_data = {
'aid': avid,
'build': 1054,
'copyright': post_video_data["archive"]["copyright"],
'cover': post_video_data["archive"]["cover"],
'desc': post_video_data["archive"]["desc"],
'no_reprint': post_video_data["archive"]["no_reprint"],
'open_elec': post_video_data["archive_elec"]["state"], # open_elec not tested
'source': post_video_data["archive"]["source"],
'tag': post_video_data["archive"]["tag"],
'tid': post_video_data["archive"]["tid"],
'title': post_video_data["archive"]["title"],
'videos': post_video_data["videos"]
}
# cover
if os.path.isfile(cover):
try:
cover = upload_cover(access_token, sid, cover)
except:
cover = ''
else:
cover = ''
# edit archive data
if copyright:
submit_data["copyright"] = copyright
if title:
submit_data["title"] = title
if tid:
submit_data["tid"] = tid
if tag:
submit_data["tag"] = tag
if desc:
submit_data["desc"] = desc
if source:
submit_data["source"] = source
if cover:
submit_data["cover"] = cover
if no_reprint:
submit_data["no_reprint"] = no_reprint
if open_elec:
submit_data["open_elec"] = open_elec
if type(insert_index) is int:
for i, video_part in enumerate(parts):
submit_data['videos'].insert(insert_index + i, {
"desc": video_part.desc,
"filename": video_part.server_file_name,
"title": video_part.title
})
elif insert_index is None:
for video_part in parts:
submit_data['videos'].append({
"desc": video_part.desc,
"filename": video_part.server_file_name,
"title": video_part.title
})
else:
print("wrong insert index")
return None, None
params = {
'access_key': access_token,
}
params['sign'] = cipher.sign_dict(params, APPSECRET)
r = requests.post(
url="http://member.bilibili.com/x/vu/client/edit",
params=params,
headers=headers,
verify=False,
cookies={
'sid': sid
},
json=submit_data,
)
print("edit submit")
print(r.status_code)
print(r.content.decode())
data = r.json()["data"]
return data["aid"], data["bvid"]

View File

@ -1 +0,0 @@
from .cipher import *

View File

@ -1,119 +0,0 @@
import hashlib
import rsa
import base64
import subprocess
import platform
import os.path
def md5(data: str):
"""
generate md5 hash of utf-8 encoded string.
"""
return hashlib.md5(data.encode("utf-8")).hexdigest()
def md5_bytes(data: bytes):
"""
generate md5 hash of binary.
"""
return hashlib.md5(data).hexdigest()
def sign_str(data: str, app_secret: str):
"""
sign a string of request parameters
Args:
data: string of request parameters, must be sorted by key before input.
app_secret: a secret string coupled with app_key.
Returns:
A hash string. len=32
"""
return md5(data + app_secret)
def sign_dict(data: dict, app_secret: str):
"""
sign a dictionary of request parameters
Args:
data: dictionary of request parameters.
app_secret: a secret string coupled with app_key.
Returns:
A hash string. len=32
"""
data_str = []
keys = list(data.keys())
keys.sort()
for key in keys:
data_str.append("{}={}".format(key, data[key]))
data_str = "&".join(data_str)
data_str = data_str + app_secret
return md5(data_str)
def login_sign_dict_bin(data: dict):
data_str = []
keys = list(data.keys())
keys.sort()
for key in keys:
data_str.append("{}={}".format(key, data[key]))
data_str = "&".join(data_str)
package_directory = os.path.dirname(os.path.abspath(__file__))
if platform.system().lower() == 'windows':
print(data_str)
print(subprocess.Popen([os.path.join(package_directory, "sign.exe"), data_str], stdout=subprocess.PIPE).communicate()[0].decode().strip())
return subprocess.Popen([os.path.join(package_directory, "sign.exe"), data_str], stdout=subprocess.PIPE).communicate()[0].decode().strip()
if platform.system().lower() == 'linux':
return subprocess.Popen([os.path.join(package_directory, "sign.out"), data_str], stdout=subprocess.PIPE).communicate()[0].decode().strip()
raise Exception("Operating System is not supported.")
def encrypt_login_password(password, hash, pubkey):
"""
encrypt password for login api.
Args:
password: plain text of user password.
hash: hash provided by /api/oauth2/getKey.
pubkey: public key provided by /api/oauth2/getKey.
Returns:
An encrypted cipher of password.
"""
return base64.b64encode(rsa.encrypt(
(hash + password).encode('utf-8'),
rsa.PublicKey.load_pkcs1_openssl_pem(pubkey.encode()),
))
def av2bv(av: int):
table = 'fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'
tr = {}
for i in range(58):
tr[table[i]] = i
s = [11, 10, 3, 8, 4, 6]
xor = 177451812
add = 8728348608
av = (av ^ xor) + add
r = list('BV1 4 1 7 ')
for i in range(6):
r[s[i]] = table[av // 58 ** i % 58]
return ''.join(r)
def bv2av(bv: str):
table = 'fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'
tr = {}
for i in range(58):
tr[table[i]] = i
s = [11, 10, 3, 8, 4, 6]
xor = 177451812
add = 8728348608
r = 0
for i in range(6):
r += tr[bv[s[i]]] * 58 ** i
return (r - add) ^ xor

View File

@ -1,18 +0,0 @@
class Retry:
def __init__(self, max_retry, success_return_value):
self.max_retry = max_retry
self.success_return_value = success_return_value
def run(self, func, *args, **kwargs):
status = False
for i in range(0, self.max_retry):
try:
return_value = func(*args, **kwargs)
except Exception:
return_value = not self.success_return_value
if return_value == self.success_return_value:
status = True
break
return status

Binary file not shown.

Binary file not shown.

BIN
ico.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@ -1,153 +0,0 @@
import time
from datetime import datetime
import threading
import Common
import os
import requests
session = requests.session()
def download():
while Common.api.isLive and not Common.forceNotDownload:
if not Common.streamUrl:
Common.appendError("Download with No StreamUrl Specific")
break
path = datetime.strftime(datetime.now(), "%Y%m%d_%H%M.flv")
base_path = Common.config["path"]
if not os.path.isdir(base_path):
os.makedirs(base_path)
try:
p = session.get(Common.streamUrl, stream=True, timeout=3)
p.raise_for_status()
except Exception as e:
Common.appendError("Download >{}< with Exception [{}]".format(path,e.__str__()))
break
Common.api.initSave(os.path.join(base_path, path)+".xml")
Common.appendDownloadStatus("Download >{}< Start".format(path))
f = open(os.path.join(base_path, path), "wb")
_size = 0
try:
for T in p.iter_content(chunk_size=Common.config["c_s"]):
if Common.forceNotDownload:
Common.modifyLastDownloadStatus("Force Stop Download".format(path))
return
f.write(T)
_size += len(T)
Common.modifyLastDownloadStatus(
"Downloading >{}< @ {:.2f}%".format(path, 100.0 * _size / Common.config["p_s"]))
if _size > Common.config["p_s"] and not Common.config["dlO"]:
Common.modifyLastDownloadStatus("Download >{}< Exceed MaxSize".format(path))
break
Common.modifyLastDownloadStatus("Download >{}< Finished".format(path))
except Exception as e:
Common.appendError("Download >{}< With Exception {}".format(path, e.__str__()))
Common.api.updRoomInfo(True)
finally:
f.close()
if os.path.getsize(os.path.join(base_path, path)) < Common.config["i_s"]:
Common.modifyLastDownloadStatus("Downloaded File >{}< is too small, will ignore it".format(path))
else:
Common.encodeQueue.put(os.path.join(base_path, path))
Common.doUpdatePlaylist()
Common.api.updRoomInfo(True)
def encode():
Common.appendEncodeStatus("Encode Daemon Starting")
while True:
i = Common.encodeQueue.get()
Common.encodeVideo(i)
def upload():
date = datetime.strftime(datetime.now(), Common.config["sdf"])
Common.appendUploadStatus("Upload Daemon Starting")
i = Common.uploadQueue.get()
while True:
if i is True:
Common.publishVideo(date)
break
try:
Common.uploadVideo(i)
except Exception as e:
Common.appendError(e.__str__())
continue
finally:
time.sleep(90)
i = Common.uploadQueue.get()
Common.appendUploadStatus("Upload Daemon Quiting")
t = threading.Thread(target=download, args=())
ut = threading.Thread(target=upload, args=())
et = threading.Thread(target=encode, args=())
def awakeEncode():
global et
if et.is_alive():
return True
et = threading.Thread(target=encode, args=())
et.setDaemon(True)
et.start()
return False
def awakeDownload():
global t
if t.is_alive():
return True
t = threading.Thread(target=download, args=())
t.setDaemon(True)
t.start()
Common.api.updRoomInfo()
return False
def awakeUpload():
global ut
if ut.is_alive():
return True
ut = threading.Thread(target=upload, args=())
ut.setDaemon(True)
ut.start()
return False
def run():
Common.refreshDownloader()
if not Common.api.isValidUser:
Common.appendError("[{}]用户未找到".format(Common.api.name))
return
while True:
if Common.api.isLive and not Common.forceNotBroadcasting:
if not Common.forceNotDownload:
awakeDownload()
if not Common.forceNotUpload:
awakeUpload()
if not Common.forceNotEncode:
awakeEncode()
try:
Common.api.getDanmaku()
except Exception as e:
Common.appendError(e.__str__())
finally:
time.sleep(1)
else:
try:
Common.api.updRoomInfo()
except Exception as e:
Common.appendError(e.__str__())
Common.refreshDownloader()
if not Common.api.broadcaster:
Common.refreshDownloader()
if Common.forceStartEncodeThread:
awakeEncode()
Common.forceStartEncodeThread = False
if Common.forceStartUploadThread:
awakeUpload()
Common.forceStartUploadThread = False
if Common.doDelay():
Common.uploadQueue.put(True)
time.sleep(5)

View File

@ -1,12 +0,0 @@
psutil>=5.9.0
certifi>=2020.4.5.1
chardet>=3.0.4
idna>=2.9
pyasn1>=0.4.8
requests>=2.23.0
rsa>=4.0
urllib3>=1.25.9
flask>=2.0.2
flask_cors>=3.0.10
protobuf>=3.19.3
python-dotenv>=0.19.2

View File

@ -1,25 +0,0 @@
function deviceUpdate(){
$.ajax(
"/stats/device",
{
success: function (res){
$("#memTotal").text(res.data.status.memTotal)
$("#memUsed").text(res.data.status.memUsed)
$("#memUsage").text(res.data.status.memUsage)
$("#diskTotal").text(res.data.status.diskTotal)
$("#diskUsed").text(res.data.status.diskUsed)
$("#diskUsage").text(res.data.status.diskUsage)
$("#cpu").text(res.data.status.cpu)
$("#memUsageP").val(res.data.status.memUsage)
$("#diskUsageP").val(res.data.status.diskUsage)
$("#cpuP").val(res.data.status.cpu)
$("#inSpeed").text(res.data.status.inSpeed)
$("#outSpeed").text(res.data.status.outSpeed)
$("#doCleanTime").text(res.data.status.doCleanTime)
}
}
)
}
deviceUpdate()
setInterval(deviceUpdate,2000)

View File

@ -1,59 +0,0 @@
function taskUpdate(){
$.ajax(
"/stats",
{
success: function (res){
$("#broadcaster").text(res.data.broadcast.broadcaster)
$("#isBroadcasting").text(res.data.broadcast.isBroadcasting)
$("#streamUrl").text(res.data.broadcast.streamUrl)
$("#delayTime").text(res.data.broadcast.delayTime)
$("#forceNotBroadcasting").text(res.data.config.forceNotBroadcasting)
$("#forceNotDownload").text(res.data.config.forceNotDownload)
$("#forceNotUpload").text(res.data.config.forceNotUpload)
$("#forceNotEncode").text(res.data.config.forceNotEncode)
$("#downloadOnly").text(res.data.config.downloadOnly)
$("#updateTime").text(res.data.broadcast.updateTime)
$("#encodeQueueSize").text(res.data.encodeQueueSize)
$("#uploadQueueSize").text(res.data.uploadQueueSize)
$("#download").html(function(){
var ret = ""
res.data.download.reverse().forEach(function(obj){
ret += "<tr><td class='time'>" + obj.datetime + "</td><td>" + obj.message + "</td></tr>"
})
return "<table>" + ret + "</table>"
})
$("#encode").html(function(){
var ret = ""
res.data.encode.reverse().forEach(function(obj){
ret += "<tr><td class='time'>" + obj.datetime + "</td><td>" + obj.message + "</td></tr>"
})
return "<table>" + ret + "</table>"
})
$("#upload").html(function(){
var ret = ""
res.data.upload.reverse().forEach(function(obj){
ret += "<tr><td class='time'>" + obj.datetime + "</td><td>" + obj.message + "</td></tr>"
})
return "<table>" + ret + "</table>"
})
$("#error").html(function(){
var ret = ""
res.data.error.reverse().forEach(function(obj){
ret += "<tr><td class='time'>" + obj.datetime + "</td><td>" + obj.message + "</td></tr>"
})
return "<table>" + ret + "</table>"
})
$("#operation").html(function(){
var ret = ""
res.data.operation.reverse().forEach(function(obj){
ret += "<tr><td class='time'>" + obj.datetime + "</td><td>" + obj.message + "</td></tr>"
})
return "<table>" + ret + "</table>"
})
}
}
)
}
taskUpdate()
setInterval(taskUpdate,8000)

View File

@ -1,30 +0,0 @@
<h1>机器状态</h1>
<table>
<tr>
<td class='title'>CPU使用率</td>
<td><progress id="cpuP" max="100" value="0"></progress></td>
<td><span id="cpu"></span>%</td>
</tr>
<tr>
<td class='title'>内存使用率</td>
<td><progress id="memUsageP" max="100" value="0"></progress></td>
<td><span id="memUsed"></span>/<span id="memTotal"></span>(<span id="memUsage"></span>%)</td>
</tr>
<tr>
<td class='title'>磁盘使用率</td>
<td><progress id="diskUsageP" max="100" value="0"></progress></td>
<td><span id="diskUsed"></span>/<span id="diskTotal"></span>(<span id="diskUsage"></span>%)</td>
</tr>
<tr>
<td class='title'>网络速率</td>
<td><span id="inSpeed"></span>/s</td>
<td><span id="outSpeed"></span>/s</td>
</tr>
<tr>
<td class='title'>文件清理</td>
<td></td>
<td>@ <span id="doCleanTime"></span></td>
</tr>
</table>
<script src="/static/device.js"></script>

View File

@ -1,26 +0,0 @@
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<title>文件</title>
{% include 'head.html' %}
</head>
<body>
<div>
<h1>所有录像文件</h1>
<p>部分录像文件已转移至百度云,请在<a href="https://pan.baidu.com/s/1ECnwiHnsm-3dSXNJGWlR2g">这里</a>下载 提取码: ddxt</p>
<table>
<tr>
<td>文件名</td><td>文件大小</td><td>链接</td>
</tr>
{%for i in files %}
<tr>
<td>{{i.name}}</td><td>{{i.size}}</td><td><a href="/files/download/{{i.name}}">下载文件</a></td>
</tr>
{% endfor %}
</table>
<hr/>
<h3><a href="/">录播信息页</a></h3>
{% include 'device.html' %}
</div>
</body>
</html>

View File

@ -1,13 +0,0 @@
<meta charset="UTF-8">
<script src="https://cdn.staticfile.org/jquery/3.3.1/jquery.min.js"></script>
<style>
td{
border: solid 1px lightgray;
}
.title{
width: 6em;
}
.time{
width: 10em;
}
</style>

View File

@ -1,86 +0,0 @@
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<title>录播</title>
{% include 'head.html' %}
</head>
<body>
<div>
<h1>基本信息</h1>
<table>
<tr>
<td>主播名</td>
<td><span id="broadcaster"></span></td>
</tr>
<tr>
<td>是否正在直播</td>
<td><span id="isBroadcasting"></span></td>
</tr>
<tr>
<td>直播视频流地址</td>
<td><span id="streamUrl"></span></td>
</tr>
<tr>
<td>信息更新时间</td>
<td><span id="updateTime"></span></td>
</tr>
<tr>
<td>延迟投稿时间</td>
<td><span id="delayTime"></span></td>
</tr>
</table>
<hr/>
<h1>特殊设置</h1>
<table>
<tr>
<td>是否设置强制认为不直播</td>
<td><span id="forceNotBroadcasting"></span></td>
</tr>
<tr>
<td>是否设置强制不下载</td>
<td><span id="forceNotDownload"></span></td>
</tr>
<tr>
<td>是否设置强制不上传</td>
<td><span id="forceNotUpload"></span></td>
</tr>
<tr>
<td>是否设置强制不转码</td>
<td><span id="forceNotEncode"></span></td>
</tr>
<tr>
<td>是否设置为仅下载(不上传不转码)</td>
<td><span id="downloadOnly"></span></td>
</tr>
</table>
<hr/>
<h1>当前状态</h1>
<table>
<tr>
<td class='title'>下载日志</td>
<td><span id="download"></span></td>
</tr>
<tr>
<td class='title'>转码日志<br>队列<span id="encodeQueueSize"></span></td>
<td><span id="encode"></span></td>
</tr>
<tr>
<td class='title'>上传日志<br>队列<span id="uploadQueueSize"></span></td>
<td><span id="upload"></span></td>
</tr>
<tr>
<td class='title'>错误日志</td>
<td><span id="error"></span></td>
</tr>
<tr>
<td class='title'>操作日志</td>
<td><span id="operation"></span></td>
</tr>
</table>
<hr/>
<h3><a href="/files/">所有录播文件</a></h3>
{% include 'device.html' %}
</div>
<script src="../static/index.js"></script>
</body>
</html>