mirror of
https://github.com/xfgryujk/blivechat.git
synced 2025-03-12 18:50:45 +08:00
添加勋章
This commit is contained in:
parent
fe598369b7
commit
ef4c0daede
BIN
frontend/public/static/img/icons/guard-level-1.png
Normal file
BIN
frontend/public/static/img/icons/guard-level-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.7 KiB |
BIN
frontend/public/static/img/icons/guard-level-2.png
Normal file
BIN
frontend/public/static/img/icons/guard-level-2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
BIN
frontend/public/static/img/icons/guard-level-3.png
Normal file
BIN
frontend/public/static/img/icons/guard-level-3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
121
frontend/src/components/ChatRenderer/AuthorBadge.vue
Normal file
121
frontend/src/components/ChatRenderer/AuthorBadge.vue
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
<template>
|
||||||
|
<yt-live-chat-author-badge-renderer :type="authorTypeText" v-if="isAdmin || privilegeType > 0">
|
||||||
|
<el-tooltip :content="readableAuthorTypeText" placement="top">
|
||||||
|
<div id="image" class="style-scope yt-live-chat-author-badge-renderer">
|
||||||
|
<yt-icon v-if="isAdmin" class="style-scope yt-live-chat-author-badge-renderer">
|
||||||
|
<svg viewBox="0 0 16 16" class="style-scope yt-icon" preserveAspectRatio="xMidYMid meet" focusable="false"
|
||||||
|
style="pointer-events: none; display: block; width: 100%; height: 100%;"
|
||||||
|
>
|
||||||
|
<g class="style-scope yt-icon">
|
||||||
|
<path class="style-scope yt-icon"
|
||||||
|
d="M9.64589146,7.05569719 C9.83346524,6.562372 9.93617022,6.02722257 9.93617022,5.46808511 C9.93617022,3.00042984 7.93574038,1 5.46808511,1 C4.90894765,1 4.37379823,1.10270499 3.88047304,1.29027875 L6.95744681,4.36725249 L4.36725255,6.95744681 L1.29027875,3.88047305 C1.10270498,4.37379824 1,4.90894766 1,5.46808511 C1,7.93574038 3.00042984,9.93617022 5.46808511,9.93617022 C6.02722256,9.93617022 6.56237198,9.83346524 7.05569716,9.64589147 L12.4098057,15 L15,12.4098057 L9.64589146,7.05569719 Z"
|
||||||
|
></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</yt-icon>
|
||||||
|
<img v-else :src="`/static/img/icons/guard-level-${privilegeType}.png`"
|
||||||
|
class="style-scope yt-live-chat-author-badge-renderer" :alt="readableAuthorTypeText">
|
||||||
|
</div>
|
||||||
|
</el-tooltip>
|
||||||
|
</yt-live-chat-author-badge-renderer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as constants from './constants'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AuthorBadge',
|
||||||
|
props: {
|
||||||
|
isAdmin: Boolean,
|
||||||
|
privilegeType: Number
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
authorTypeText() {
|
||||||
|
if (this.isAdmin) {
|
||||||
|
return 'moderator'
|
||||||
|
}
|
||||||
|
return this.privilegeType > 0 ? 'member' : ''
|
||||||
|
},
|
||||||
|
readableAuthorTypeText() {
|
||||||
|
if (this.isAdmin) {
|
||||||
|
return '管理员'
|
||||||
|
}
|
||||||
|
return constants.GUARD_LEVEL_TO_TEXT[this.privilegeType]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- yt-live-chat-author-badge-renderer -->
|
||||||
|
<style>
|
||||||
|
canvas.yt-live-chat-author-badge-renderer, caption.yt-live-chat-author-badge-renderer, center.yt-live-chat-author-badge-renderer, cite.yt-live-chat-author-badge-renderer, code.yt-live-chat-author-badge-renderer, dd.yt-live-chat-author-badge-renderer, del.yt-live-chat-author-badge-renderer, dfn.yt-live-chat-author-badge-renderer, div.yt-live-chat-author-badge-renderer, dl.yt-live-chat-author-badge-renderer, dt.yt-live-chat-author-badge-renderer, em.yt-live-chat-author-badge-renderer, embed.yt-live-chat-author-badge-renderer, fieldset.yt-live-chat-author-badge-renderer, font.yt-live-chat-author-badge-renderer, form.yt-live-chat-author-badge-renderer, h1.yt-live-chat-author-badge-renderer, h2.yt-live-chat-author-badge-renderer, h3.yt-live-chat-author-badge-renderer, h4.yt-live-chat-author-badge-renderer, h5.yt-live-chat-author-badge-renderer, h6.yt-live-chat-author-badge-renderer, hr.yt-live-chat-author-badge-renderer, i.yt-live-chat-author-badge-renderer, iframe.yt-live-chat-author-badge-renderer, img.yt-live-chat-author-badge-renderer, ins.yt-live-chat-author-badge-renderer, kbd.yt-live-chat-author-badge-renderer, label.yt-live-chat-author-badge-renderer, legend.yt-live-chat-author-badge-renderer, li.yt-live-chat-author-badge-renderer, menu.yt-live-chat-author-badge-renderer, object.yt-live-chat-author-badge-renderer, ol.yt-live-chat-author-badge-renderer, p.yt-live-chat-author-badge-renderer, pre.yt-live-chat-author-badge-renderer, q.yt-live-chat-author-badge-renderer, s.yt-live-chat-author-badge-renderer, samp.yt-live-chat-author-badge-renderer, small.yt-live-chat-author-badge-renderer, span.yt-live-chat-author-badge-renderer, strike.yt-live-chat-author-badge-renderer, strong.yt-live-chat-author-badge-renderer, sub.yt-live-chat-author-badge-renderer, sup.yt-live-chat-author-badge-renderer, table.yt-live-chat-author-badge-renderer, tbody.yt-live-chat-author-badge-renderer, td.yt-live-chat-author-badge-renderer, tfoot.yt-live-chat-author-badge-renderer, th.yt-live-chat-author-badge-renderer, thead.yt-live-chat-author-badge-renderer, tr.yt-live-chat-author-badge-renderer, tt.yt-live-chat-author-badge-renderer, u.yt-live-chat-author-badge-renderer, ul.yt-live-chat-author-badge-renderer, var.yt-live-chat-author-badge-renderer {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-live-chat-author-badge-renderer[hidden] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
yt-live-chat-author-badge-renderer {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
yt-live-chat-author-badge-renderer[type='moderator'] {
|
||||||
|
color: var(--yt-live-chat-moderator-color, #5e84f1);
|
||||||
|
}
|
||||||
|
|
||||||
|
yt-live-chat-author-badge-renderer[type='owner'] {
|
||||||
|
color: var(--yt-live-chat-owner-color, #ffd600);
|
||||||
|
}
|
||||||
|
|
||||||
|
yt-live-chat-author-badge-renderer[type='member'] {
|
||||||
|
color: var(--yt-live-chat-sponsor-color, #107516);
|
||||||
|
}
|
||||||
|
|
||||||
|
yt-live-chat-author-badge-renderer[type='verified'] {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.yt-live-chat-author-badge-renderer, yt-icon.yt-live-chat-author-badge-renderer {
|
||||||
|
display: block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- yt-icon -->
|
||||||
|
<style>
|
||||||
|
canvas.yt-icon, caption.yt-icon, center.yt-icon, cite.yt-icon, code.yt-icon, dd.yt-icon, del.yt-icon, dfn.yt-icon, div.yt-icon, dl.yt-icon, dt.yt-icon, em.yt-icon, embed.yt-icon, fieldset.yt-icon, font.yt-icon, form.yt-icon, h1.yt-icon, h2.yt-icon, h3.yt-icon, h4.yt-icon, h5.yt-icon, h6.yt-icon, hr.yt-icon, i.yt-icon, iframe.yt-icon, img.yt-icon, ins.yt-icon, kbd.yt-icon, label.yt-icon, legend.yt-icon, li.yt-icon, menu.yt-icon, object.yt-icon, ol.yt-icon, p.yt-icon, pre.yt-icon, q.yt-icon, s.yt-icon, samp.yt-icon, small.yt-icon, span.yt-icon, strike.yt-icon, strong.yt-icon, sub.yt-icon, sup.yt-icon, table.yt-icon, tbody.yt-icon, td.yt-icon, tfoot.yt-icon, th.yt-icon, thead.yt-icon, tr.yt-icon, tt.yt-icon, u.yt-icon, ul.yt-icon, var.yt-icon {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-icon[hidden] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
yt-icon, .yt-icon-container.yt-icon {
|
||||||
|
display: inline-flex;
|
||||||
|
-ms-flex-align: center;
|
||||||
|
-webkit-align-items: center;
|
||||||
|
align-items: center;
|
||||||
|
-ms-flex-pack: center;
|
||||||
|
-webkit-justify-content: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: middle;
|
||||||
|
fill: currentcolor;
|
||||||
|
stroke: none;
|
||||||
|
width: var(--iron-icon-width, 24px);
|
||||||
|
height: var(--iron-icon-height, 24px);
|
||||||
|
}
|
||||||
|
|
||||||
|
yt-icon.external-container {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
</style>
|
88
frontend/src/components/ChatRenderer/ImgShadow.vue
Normal file
88
frontend/src/components/ChatRenderer/ImgShadow.vue
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
<template>
|
||||||
|
<yt-img-shadow class="no-transition" :height="height" :width="width" style="background-color: transparent;" loaded>
|
||||||
|
<img id="img" class="style-scope yt-img-shadow" alt="" :height="height" :width="width" :src="imgUrl">
|
||||||
|
</yt-img-shadow>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'ImgShadow',
|
||||||
|
props: {
|
||||||
|
imgUrl: String,
|
||||||
|
height: String,
|
||||||
|
width: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- yt-img-shadow -->
|
||||||
|
<style>
|
||||||
|
canvas.yt-img-shadow, caption.yt-img-shadow, center.yt-img-shadow, cite.yt-img-shadow, code.yt-img-shadow, dd.yt-img-shadow, del.yt-img-shadow, dfn.yt-img-shadow, div.yt-img-shadow, dl.yt-img-shadow, dt.yt-img-shadow, em.yt-img-shadow, embed.yt-img-shadow, fieldset.yt-img-shadow, font.yt-img-shadow, form.yt-img-shadow, h1.yt-img-shadow, h2.yt-img-shadow, h3.yt-img-shadow, h4.yt-img-shadow, h5.yt-img-shadow, h6.yt-img-shadow, hr.yt-img-shadow, i.yt-img-shadow, iframe.yt-img-shadow, img.yt-img-shadow, ins.yt-img-shadow, kbd.yt-img-shadow, label.yt-img-shadow, legend.yt-img-shadow, li.yt-img-shadow, menu.yt-img-shadow, object.yt-img-shadow, ol.yt-img-shadow, p.yt-img-shadow, pre.yt-img-shadow, q.yt-img-shadow, s.yt-img-shadow, samp.yt-img-shadow, small.yt-img-shadow, span.yt-img-shadow, strike.yt-img-shadow, strong.yt-img-shadow, sub.yt-img-shadow, sup.yt-img-shadow, table.yt-img-shadow, tbody.yt-img-shadow, td.yt-img-shadow, tfoot.yt-img-shadow, th.yt-img-shadow, thead.yt-img-shadow, tr.yt-img-shadow, tt.yt-img-shadow, u.yt-img-shadow, ul.yt-img-shadow, var.yt-img-shadow {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yt-img-shadow[hidden] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
yt-img-shadow {
|
||||||
|
display: inline-block;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
-ms-flex: none;
|
||||||
|
-webkit-flex: none;
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
yt-img-shadow.no-transition {
|
||||||
|
opacity: 1;
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
yt-img-shadow.with-placeholder {
|
||||||
|
background-color: transparent;
|
||||||
|
min-height: unset;
|
||||||
|
min-width: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
yt-img-shadow[loaded] {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
yt-img-shadow.empty img.yt-img-shadow {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
yt-img-shadow[object-fit="FILL"] img.yt-img-shadow, yt-img-shadow[fit] img.yt-img-shadow {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
yt-img-shadow[object-fit="COVER"] img.yt-img-shadow {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
yt-img-shadow[object-fit="CONTAIN"] img.yt-img-shadow {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
yt-img-shadow[object-position="LEFT"] img.yt-img-shadow {
|
||||||
|
object-position: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.yt-img-shadow {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
max-height: none;
|
||||||
|
max-width: 100%;
|
||||||
|
border-radius: none;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,11 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<yt-live-chat-legacy-paid-message-renderer class="style-scope yt-live-chat-item-list-renderer">
|
<yt-live-chat-legacy-paid-message-renderer class="style-scope yt-live-chat-item-list-renderer">
|
||||||
<div id="card" class="style-scope yt-live-chat-legacy-paid-message-renderer">
|
<div id="card" class="style-scope yt-live-chat-legacy-paid-message-renderer">
|
||||||
<yt-img-shadow id="author-photo" class="style-scope yt-live-chat-legacy-paid-message-renderer no-transition"
|
<img-shadow id="author-photo" height="40" width="40" class="style-scope yt-live-chat-legacy-paid-message-renderer"
|
||||||
height="40" width="40" style="background-color: transparent;" loaded
|
:imgUrl="avatarUrl"
|
||||||
>
|
></img-shadow>
|
||||||
<img id="img" class="style-scope yt-img-shadow" alt="" height="40" width="40" :src="avatarUrl">
|
|
||||||
</yt-img-shadow>
|
|
||||||
<div id="content" class="style-scope yt-live-chat-legacy-paid-message-renderer">
|
<div id="content" class="style-scope yt-live-chat-legacy-paid-message-renderer">
|
||||||
<div id="content-primary-column" class="style-scope yt-live-chat-legacy-paid-message-renderer">
|
<div id="content-primary-column" class="style-scope yt-live-chat-legacy-paid-message-renderer">
|
||||||
<div id="author-name" class="style-scope yt-live-chat-legacy-paid-message-renderer">{{authorName}}</div>
|
<div id="author-name" class="style-scope yt-live-chat-legacy-paid-message-renderer">{{authorName}}</div>
|
||||||
@ -22,8 +20,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import ImgShadow from './ImgShadow.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'LegacyPaidMessage',
|
name: 'LegacyPaidMessage',
|
||||||
|
components: {
|
||||||
|
ImgShadow
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
avatarUrl: String,
|
avatarUrl: String,
|
||||||
authorName: String,
|
authorName: String,
|
||||||
|
@ -10,11 +10,9 @@
|
|||||||
>
|
>
|
||||||
<div id="card" class="style-scope yt-live-chat-paid-message-renderer">
|
<div id="card" class="style-scope yt-live-chat-paid-message-renderer">
|
||||||
<div id="header" class="style-scope yt-live-chat-paid-message-renderer">
|
<div id="header" class="style-scope yt-live-chat-paid-message-renderer">
|
||||||
<yt-img-shadow id="author-photo" class="style-scope yt-live-chat-legacy-paid-message-renderer no-transition"
|
<img-shadow id="author-photo" height="40" width="40" class="style-scope yt-live-chat-paid-message-renderer"
|
||||||
height="40" width="40" style="background-color: transparent;" loaded
|
:imgUrl="avatarUrl"
|
||||||
>
|
></img-shadow>
|
||||||
<img id="img" class="style-scope yt-img-shadow" alt="" height="40" width="40" :src="avatarUrl">
|
|
||||||
</yt-img-shadow>
|
|
||||||
<div id="header-content" class="style-scope yt-live-chat-paid-message-renderer">
|
<div id="header-content" class="style-scope yt-live-chat-paid-message-renderer">
|
||||||
<div id="header-content-primary-column" class="style-scope yt-live-chat-paid-message-renderer">
|
<div id="header-content-primary-column" class="style-scope yt-live-chat-paid-message-renderer">
|
||||||
<div id="author-name" class="style-scope yt-live-chat-paid-message-renderer">{{authorName}}</div>
|
<div id="author-name" class="style-scope yt-live-chat-paid-message-renderer">{{authorName}}</div>
|
||||||
@ -33,6 +31,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import ImgShadow from './ImgShadow.vue'
|
||||||
|
|
||||||
const COLORS = [
|
const COLORS = [
|
||||||
{ // $100红
|
{ // $100红
|
||||||
price: 1245, // >= 1245,小电视飞船
|
price: 1245, // >= 1245,小电视飞船
|
||||||
@ -95,6 +95,9 @@ const COLORS = [
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PaidMessage',
|
name: 'PaidMessage',
|
||||||
|
components: {
|
||||||
|
ImgShadow
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
avatarUrl: String,
|
avatarUrl: String,
|
||||||
authorName: String,
|
authorName: String,
|
||||||
|
@ -1,18 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<yt-live-chat-text-message-renderer :author-type="authorTypeText">
|
<yt-live-chat-text-message-renderer :author-type="authorTypeText">
|
||||||
<yt-img-shadow id="author-photo" class="no-transition style-scope yt-live-chat-text-message-renderer" height="24"
|
<img-shadow id="author-photo" height="24" width="24" class="style-scope yt-live-chat-text-message-renderer"
|
||||||
width="24" style="background-color: transparent;" loaded
|
:imgUrl="avatarUrl"
|
||||||
>
|
></img-shadow>
|
||||||
<img id="img" class="style-scope yt-img-shadow" alt="" height="24" width="24" :src="avatarUrl">
|
|
||||||
</yt-img-shadow>
|
|
||||||
<div id="content" class="style-scope yt-live-chat-text-message-renderer">
|
<div id="content" class="style-scope yt-live-chat-text-message-renderer">
|
||||||
<span id="timestamp" class="style-scope yt-live-chat-text-message-renderer">{{time}}</span>
|
<span id="timestamp" class="style-scope yt-live-chat-text-message-renderer">{{time}}</span>
|
||||||
<yt-live-chat-author-chip class="style-scope yt-live-chat-text-message-renderer">
|
<yt-live-chat-author-chip class="style-scope yt-live-chat-text-message-renderer">
|
||||||
<span id="author-name" dir="auto" class="style-scope yt-live-chat-author-chip" :type="authorTypeText">
|
<span id="author-name" dir="auto" class="style-scope yt-live-chat-author-chip" :type="authorTypeText">
|
||||||
{{authorName}}
|
{{authorName}}
|
||||||
|
<!-- 这里是已验证勋章 -->
|
||||||
<span id="chip-badges" class="style-scope yt-live-chat-author-chip"></span>
|
<span id="chip-badges" class="style-scope yt-live-chat-author-chip"></span>
|
||||||
</span>
|
</span>
|
||||||
<span id="chat-badges" class="style-scope yt-live-chat-author-chip"></span>
|
<span id="chat-badges" class="style-scope yt-live-chat-author-chip">
|
||||||
|
<author-badge class="style-scope yt-live-chat-author-chip"
|
||||||
|
:isAdmin="authorType === 2" :privilegeType="privilegeType"
|
||||||
|
></author-badge>
|
||||||
|
</span>
|
||||||
</yt-live-chat-author-chip>
|
</yt-live-chat-author-chip>
|
||||||
<span id="message" class="style-scope yt-live-chat-text-message-renderer">{{content}}</span>
|
<span id="message" class="style-scope yt-live-chat-text-message-renderer">{{content}}</span>
|
||||||
<el-badge :value="repeated" :max="99" v-show="repeated > 1" class="style-scope yt-live-chat-text-message-renderer"
|
<el-badge :value="repeated" :max="99" v-show="repeated > 1" class="style-scope yt-live-chat-text-message-renderer"
|
||||||
@ -23,28 +26,31 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const AUTHOR_TYPE_TO_TEXT = [
|
import ImgShadow from './ImgShadow.vue'
|
||||||
'',
|
import AuthorBadge from './AuthorBadge.vue'
|
||||||
'member', // 舰队
|
import * as constants from './constants'
|
||||||
'moderator', // 房管
|
|
||||||
'owner' // 主播
|
|
||||||
]
|
|
||||||
const REPEATED_MARK_COLOR_START = [64, 158, 255]
|
const REPEATED_MARK_COLOR_START = [64, 158, 255]
|
||||||
const REPEATED_MARK_COLOR_END = [245, 108, 108]
|
const REPEATED_MARK_COLOR_END = [245, 108, 108]
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TextMessage',
|
name: 'TextMessage',
|
||||||
|
components: {
|
||||||
|
ImgShadow,
|
||||||
|
AuthorBadge
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
avatarUrl: String,
|
avatarUrl: String,
|
||||||
time: String,
|
time: String,
|
||||||
authorName: String,
|
authorName: String,
|
||||||
authorType: Number,
|
authorType: Number,
|
||||||
content: String,
|
content: String,
|
||||||
|
privilegeType: Number,
|
||||||
repeated: Number
|
repeated: Number
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
authorTypeText() {
|
authorTypeText() {
|
||||||
return AUTHOR_TYPE_TO_TEXT[this.authorType]
|
return constants.AUTHOR_TYPE_TO_TEXT[this.authorType]
|
||||||
},
|
},
|
||||||
repeatedMarkColor() {
|
repeatedMarkColor() {
|
||||||
let color
|
let color
|
||||||
@ -313,78 +319,6 @@ yt-live-chat-text-message-renderer[is-dimmed]::before {
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<!-- yt-img-shadow -->
|
|
||||||
<style>
|
|
||||||
canvas.yt-img-shadow, caption.yt-img-shadow, center.yt-img-shadow, cite.yt-img-shadow, code.yt-img-shadow, dd.yt-img-shadow, del.yt-img-shadow, dfn.yt-img-shadow, div.yt-img-shadow, dl.yt-img-shadow, dt.yt-img-shadow, em.yt-img-shadow, embed.yt-img-shadow, fieldset.yt-img-shadow, font.yt-img-shadow, form.yt-img-shadow, h1.yt-img-shadow, h2.yt-img-shadow, h3.yt-img-shadow, h4.yt-img-shadow, h5.yt-img-shadow, h6.yt-img-shadow, hr.yt-img-shadow, i.yt-img-shadow, iframe.yt-img-shadow, img.yt-img-shadow, ins.yt-img-shadow, kbd.yt-img-shadow, label.yt-img-shadow, legend.yt-img-shadow, li.yt-img-shadow, menu.yt-img-shadow, object.yt-img-shadow, ol.yt-img-shadow, p.yt-img-shadow, pre.yt-img-shadow, q.yt-img-shadow, s.yt-img-shadow, samp.yt-img-shadow, small.yt-img-shadow, span.yt-img-shadow, strike.yt-img-shadow, strong.yt-img-shadow, sub.yt-img-shadow, sup.yt-img-shadow, table.yt-img-shadow, tbody.yt-img-shadow, td.yt-img-shadow, tfoot.yt-img-shadow, th.yt-img-shadow, thead.yt-img-shadow, tr.yt-img-shadow, tt.yt-img-shadow, u.yt-img-shadow, ul.yt-img-shadow, var.yt-img-shadow {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
border: 0;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.yt-img-shadow[hidden] {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
yt-img-shadow {
|
|
||||||
display: inline-block;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 0.2s;
|
|
||||||
-ms-flex: none;
|
|
||||||
-webkit-flex: none;
|
|
||||||
flex: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
yt-img-shadow.no-transition {
|
|
||||||
opacity: 1;
|
|
||||||
transition: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
yt-img-shadow.with-placeholder {
|
|
||||||
background-color: transparent;
|
|
||||||
min-height: unset;
|
|
||||||
min-width: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
yt-img-shadow[loaded] {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
yt-img-shadow.empty img.yt-img-shadow {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
yt-img-shadow[object-fit="FILL"] img.yt-img-shadow, yt-img-shadow[fit] img.yt-img-shadow {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
yt-img-shadow[object-fit="COVER"] img.yt-img-shadow {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
yt-img-shadow[object-fit="CONTAIN"] img.yt-img-shadow {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: contain;
|
|
||||||
}
|
|
||||||
|
|
||||||
yt-img-shadow[object-position="LEFT"] img.yt-img-shadow {
|
|
||||||
object-position: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
img.yt-img-shadow {
|
|
||||||
display: block;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
max-height: none;
|
|
||||||
max-width: 100%;
|
|
||||||
border-radius: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!-- yt-live-chat-author-chip -->
|
<!-- yt-live-chat-author-chip -->
|
||||||
<style>
|
<style>
|
||||||
canvas.yt-live-chat-author-chip, caption.yt-live-chat-author-chip, center.yt-live-chat-author-chip, cite.yt-live-chat-author-chip, code.yt-live-chat-author-chip, dd.yt-live-chat-author-chip, del.yt-live-chat-author-chip, dfn.yt-live-chat-author-chip, div.yt-live-chat-author-chip, dl.yt-live-chat-author-chip, dt.yt-live-chat-author-chip, em.yt-live-chat-author-chip, embed.yt-live-chat-author-chip, fieldset.yt-live-chat-author-chip, font.yt-live-chat-author-chip, form.yt-live-chat-author-chip, h1.yt-live-chat-author-chip, h2.yt-live-chat-author-chip, h3.yt-live-chat-author-chip, h4.yt-live-chat-author-chip, h5.yt-live-chat-author-chip, h6.yt-live-chat-author-chip, hr.yt-live-chat-author-chip, i.yt-live-chat-author-chip, iframe.yt-live-chat-author-chip, img.yt-live-chat-author-chip, ins.yt-live-chat-author-chip, kbd.yt-live-chat-author-chip, label.yt-live-chat-author-chip, legend.yt-live-chat-author-chip, li.yt-live-chat-author-chip, menu.yt-live-chat-author-chip, object.yt-live-chat-author-chip, ol.yt-live-chat-author-chip, p.yt-live-chat-author-chip, pre.yt-live-chat-author-chip, q.yt-live-chat-author-chip, s.yt-live-chat-author-chip, samp.yt-live-chat-author-chip, small.yt-live-chat-author-chip, span.yt-live-chat-author-chip, strike.yt-live-chat-author-chip, strong.yt-live-chat-author-chip, sub.yt-live-chat-author-chip, sup.yt-live-chat-author-chip, table.yt-live-chat-author-chip, tbody.yt-live-chat-author-chip, td.yt-live-chat-author-chip, tfoot.yt-live-chat-author-chip, th.yt-live-chat-author-chip, thead.yt-live-chat-author-chip, tr.yt-live-chat-author-chip, tt.yt-live-chat-author-chip, u.yt-live-chat-author-chip, ul.yt-live-chat-author-chip, var.yt-live-chat-author-chip {
|
canvas.yt-live-chat-author-chip, caption.yt-live-chat-author-chip, center.yt-live-chat-author-chip, cite.yt-live-chat-author-chip, code.yt-live-chat-author-chip, dd.yt-live-chat-author-chip, del.yt-live-chat-author-chip, dfn.yt-live-chat-author-chip, div.yt-live-chat-author-chip, dl.yt-live-chat-author-chip, dt.yt-live-chat-author-chip, em.yt-live-chat-author-chip, embed.yt-live-chat-author-chip, fieldset.yt-live-chat-author-chip, font.yt-live-chat-author-chip, form.yt-live-chat-author-chip, h1.yt-live-chat-author-chip, h2.yt-live-chat-author-chip, h3.yt-live-chat-author-chip, h4.yt-live-chat-author-chip, h5.yt-live-chat-author-chip, h6.yt-live-chat-author-chip, hr.yt-live-chat-author-chip, i.yt-live-chat-author-chip, iframe.yt-live-chat-author-chip, img.yt-live-chat-author-chip, ins.yt-live-chat-author-chip, kbd.yt-live-chat-author-chip, label.yt-live-chat-author-chip, legend.yt-live-chat-author-chip, li.yt-live-chat-author-chip, menu.yt-live-chat-author-chip, object.yt-live-chat-author-chip, ol.yt-live-chat-author-chip, p.yt-live-chat-author-chip, pre.yt-live-chat-author-chip, q.yt-live-chat-author-chip, s.yt-live-chat-author-chip, samp.yt-live-chat-author-chip, small.yt-live-chat-author-chip, span.yt-live-chat-author-chip, strike.yt-live-chat-author-chip, strong.yt-live-chat-author-chip, sub.yt-live-chat-author-chip, sup.yt-live-chat-author-chip, table.yt-live-chat-author-chip, tbody.yt-live-chat-author-chip, td.yt-live-chat-author-chip, tfoot.yt-live-chat-author-chip, th.yt-live-chat-author-chip, thead.yt-live-chat-author-chip, tr.yt-live-chat-author-chip, tt.yt-live-chat-author-chip, u.yt-live-chat-author-chip, ul.yt-live-chat-author-chip, var.yt-live-chat-author-chip {
|
||||||
|
17
frontend/src/components/ChatRenderer/constants.js
Normal file
17
frontend/src/components/ChatRenderer/constants.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
export const AUTHRO_TYPE_MEMBER = 1
|
||||||
|
export const AUTHRO_TYPE_ADMIN = 2
|
||||||
|
export const AUTHRO_TYPE_OWNER = 3
|
||||||
|
|
||||||
|
export const AUTHOR_TYPE_TO_TEXT = [
|
||||||
|
'',
|
||||||
|
'member', // 舰队
|
||||||
|
'moderator', // 房管
|
||||||
|
'owner' // 主播
|
||||||
|
]
|
||||||
|
|
||||||
|
export const GUARD_LEVEL_TO_TEXT = [
|
||||||
|
'',
|
||||||
|
'总督',
|
||||||
|
'提督',
|
||||||
|
'舰长'
|
||||||
|
]
|
@ -22,7 +22,8 @@
|
|||||||
<text-message :key="message.id" v-if="message.type == 0"
|
<text-message :key="message.id" v-if="message.type == 0"
|
||||||
class="style-scope yt-live-chat-item-list-renderer"
|
class="style-scope yt-live-chat-item-list-renderer"
|
||||||
:avatarUrl="message.avatarUrl" :time="message.time" :authorName="message.authorName"
|
:avatarUrl="message.avatarUrl" :time="message.time" :authorName="message.authorName"
|
||||||
:authorType="message.authorType" :content="message.content" :repeated="message.repeated"
|
:authorType="message.authorType" :content="message.content" :privilegeType="message.privilegeType"
|
||||||
|
:repeated="message.repeated"
|
||||||
></text-message>
|
></text-message>
|
||||||
<legacy-paid-message :key="message.id" v-else-if="message.type == 1"
|
<legacy-paid-message :key="message.id" v-else-if="message.type == 1"
|
||||||
class="style-scope yt-live-chat-item-list-renderer"
|
class="style-scope yt-live-chat-item-list-renderer"
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<el-form-item label="房间ID" required prop="roomId">
|
<el-form-item label="房间ID" required prop="roomId">
|
||||||
<el-input v-model.number="form.roomId" type="number" min="1"></el-input>
|
<el-input v-model.number="form.roomId" type="number" min="1"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="最低显示礼物价格" prop="minGiftPrice">
|
<el-form-item label="最低显示礼物价格(元)" prop="minGiftPrice">
|
||||||
<el-input v-model.number="form.minGiftPrice" type="number" min="0"></el-input>
|
<el-input v-model.number="form.minGiftPrice" type="number" min="0"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="合并相似弹幕" prop="mergeSimilarDanmaku">
|
<el-form-item label="合并相似弹幕" prop="mergeSimilarDanmaku">
|
||||||
|
@ -9,7 +9,7 @@ import ChatRenderer from '@/components/ChatRenderer'
|
|||||||
const COMMAND_JOIN_ROOM = 0
|
const COMMAND_JOIN_ROOM = 0
|
||||||
const COMMAND_ADD_TEXT = 1
|
const COMMAND_ADD_TEXT = 1
|
||||||
const COMMAND_ADD_GIFT = 2
|
const COMMAND_ADD_GIFT = 2
|
||||||
const COMMAND_ADD_VIP = 3
|
const COMMAND_ADD_MEMBER = 3
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Room',
|
name: 'Room',
|
||||||
@ -74,6 +74,7 @@ export default {
|
|||||||
authorName: data.authorName,
|
authorName: data.authorName,
|
||||||
authorType: data.authorType,
|
authorType: data.authorType,
|
||||||
content: data.content,
|
content: data.content,
|
||||||
|
privilegeType: data.privilegeType,
|
||||||
repeated: 1
|
repeated: 1
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@ -92,7 +93,7 @@ export default {
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case COMMAND_ADD_VIP:
|
case COMMAND_ADD_MEMBER:
|
||||||
message = {
|
message = {
|
||||||
id: this.nextId++,
|
id: this.nextId++,
|
||||||
type: 1, // LegacyPaidMessage
|
type: 1, // LegacyPaidMessage
|
||||||
|
@ -179,7 +179,7 @@
|
|||||||
|
|
||||||
<h3>结果</h3>
|
<h3>结果</h3>
|
||||||
<el-form-item label="CSS">
|
<el-form-item label="CSS">
|
||||||
<el-input v-model="result" ref="result" type="textarea" :rows="10"></el-input>
|
<el-input v-model="result" ref="result" type="textarea" :rows="20"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="copyResult">复制</el-button>
|
<el-button type="primary" @click="copyResult">复制</el-button>
|
||||||
@ -203,6 +203,7 @@ import _ from 'lodash'
|
|||||||
import stylegen from './stylegen'
|
import stylegen from './stylegen'
|
||||||
import fonts from './fonts'
|
import fonts from './fonts'
|
||||||
import ChatRenderer from '@/components/ChatRenderer'
|
import ChatRenderer from '@/components/ChatRenderer'
|
||||||
|
import * as constants from '@/components/ChatRenderer/constants'
|
||||||
|
|
||||||
let time = new Date()
|
let time = new Date()
|
||||||
let textMessageTemplate = {
|
let textMessageTemplate = {
|
||||||
@ -213,6 +214,7 @@ let textMessageTemplate = {
|
|||||||
authorName: '',
|
authorName: '',
|
||||||
authorType: 0,
|
authorType: 0,
|
||||||
content: '',
|
content: '',
|
||||||
|
privilegeType: 0,
|
||||||
repeated: 1
|
repeated: 1
|
||||||
}
|
}
|
||||||
let legacyPaidMessageTemplate = {
|
let legacyPaidMessageTemplate = {
|
||||||
@ -245,14 +247,15 @@ const EXAMPLE_MESSAGES = [
|
|||||||
...textMessageTemplate,
|
...textMessageTemplate,
|
||||||
id: nextId++,
|
id: nextId++,
|
||||||
authorName: 'member舰长',
|
authorName: 'member舰长',
|
||||||
authorType: 1,
|
authorType: constants.AUTHRO_TYPE_MEMBER,
|
||||||
content: '草',
|
content: '草',
|
||||||
|
privilegeType: 3,
|
||||||
repeated: 3
|
repeated: 3
|
||||||
}, {
|
}, {
|
||||||
...textMessageTemplate,
|
...textMessageTemplate,
|
||||||
id: nextId++,
|
id: nextId++,
|
||||||
authorName: 'admin房管',
|
authorName: 'admin房管',
|
||||||
authorType: 2,
|
authorType: constants.AUTHRO_TYPE_ADMIN,
|
||||||
content: 'kksk'
|
content: 'kksk'
|
||||||
}, {
|
}, {
|
||||||
...legacyPaidMessageTemplate,
|
...legacyPaidMessageTemplate,
|
||||||
@ -269,7 +272,7 @@ const EXAMPLE_MESSAGES = [
|
|||||||
...textMessageTemplate,
|
...textMessageTemplate,
|
||||||
id: nextId++,
|
id: nextId++,
|
||||||
authorName: 'streamer主播',
|
authorName: 'streamer主播',
|
||||||
authorType: 3,
|
authorType: constants.AUTHRO_TYPE_OWNER,
|
||||||
content: '感谢石油佬送的小电视'
|
content: '感谢石油佬送的小电视'
|
||||||
}, {
|
}, {
|
||||||
...paidMessageTemplate,
|
...paidMessageTemplate,
|
||||||
@ -325,11 +328,11 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
computedResult: _.debounce(function (val) {
|
computedResult: _.debounce(function(val) {
|
||||||
this.result = val
|
this.result = val
|
||||||
stylegen.setLocalConfig(this.form)
|
stylegen.setLocalConfig(this.form)
|
||||||
}, 500),
|
}, 500),
|
||||||
result (val) {
|
result(val) {
|
||||||
this.exampleCss = val.replace(/^body\b/gm, '#fakebody')
|
this.exampleCss = val.replace(/^body\b/gm, '#fakebody')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ yt-live-chat-legacy-paid-message-renderer #author-photo img {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Hide badges. */
|
/* Hide badges. */
|
||||||
yt-live-chat-text-message-renderer #author-badges {
|
yt-live-chat-text-message-renderer #chat-badges {
|
||||||
${config.showBadges ? '' : 'display: none !important;'}
|
${config.showBadges ? '' : 'display: none !important;'}
|
||||||
vertical-align: text-top !important;
|
vertical-align: text-top !important;
|
||||||
}
|
}
|
||||||
|
3
main.py
3
main.py
@ -1,6 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import webbrowser
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@ -46,6 +47,8 @@ def main():
|
|||||||
)
|
)
|
||||||
app.listen(args.port, args.host)
|
app.listen(args.port, args.host)
|
||||||
logger.info('服务器启动:%s:%d', args.host, args.port)
|
logger.info('服务器启动:%s:%d', args.host, args.port)
|
||||||
|
url = 'http://localhost' if args.port == 80 else f'http://localhost:{args.port}'
|
||||||
|
webbrowser.open(url)
|
||||||
tornado.ioloop.IOLoop.current().start()
|
tornado.ioloop.IOLoop.current().start()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import datetime
|
||||||
import enum
|
import enum
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
@ -19,20 +20,31 @@ class Command(enum.IntEnum):
|
|||||||
JOIN_ROOM = 0
|
JOIN_ROOM = 0
|
||||||
ADD_TEXT = 1
|
ADD_TEXT = 1
|
||||||
ADD_GIFT = 2
|
ADD_GIFT = 2
|
||||||
ADD_VIP = 3
|
ADD_MEMBER = 3
|
||||||
|
|
||||||
|
|
||||||
_http_session = aiohttp.ClientSession()
|
_http_session = aiohttp.ClientSession()
|
||||||
_avatar_url_cache: Dict[int, str] = {}
|
_avatar_url_cache: Dict[int, str] = {}
|
||||||
|
_last_avatar_failed_time = None
|
||||||
|
|
||||||
|
|
||||||
async def get_avatar_url(user_id):
|
async def get_avatar_url(user_id):
|
||||||
if user_id in _avatar_url_cache:
|
if user_id in _avatar_url_cache:
|
||||||
return _avatar_url_cache[user_id]
|
return _avatar_url_cache[user_id]
|
||||||
|
|
||||||
|
global _last_avatar_failed_time
|
||||||
|
if _last_avatar_failed_time is not None:
|
||||||
|
if (datetime.datetime.now() - _last_avatar_failed_time).seconds < 5 * 60:
|
||||||
|
# 5分钟以内被ban
|
||||||
|
return 'https://static.hdslb.com/images/member/noface.gif'
|
||||||
|
else:
|
||||||
|
_last_avatar_failed_time = None
|
||||||
|
|
||||||
async with _http_session.get('https://api.bilibili.com/x/space/acc/info',
|
async with _http_session.get('https://api.bilibili.com/x/space/acc/info',
|
||||||
params={'mid': user_id}) as r:
|
params={'mid': user_id}) as r:
|
||||||
if r.status != 200: # 可能会被B站ban
|
if r.status != 200: # 可能会被B站ban
|
||||||
logger.error('获取头像失败:status=%d %s uid=%d', r.status, r.reason, user_id)
|
logger.warning('获取头像失败:status=%d %s uid=%d', r.status, r.reason, user_id)
|
||||||
|
_last_avatar_failed_time = datetime.datetime.now()
|
||||||
return 'https://static.hdslb.com/images/member/noface.gif'
|
return 'https://static.hdslb.com/images/member/noface.gif'
|
||||||
data = await r.json()
|
data = await r.json()
|
||||||
url = data['data']['face']
|
url = data['data']['face']
|
||||||
@ -40,7 +52,7 @@ async def get_avatar_url(user_id):
|
|||||||
url += '@48w_48h'
|
url += '@48w_48h'
|
||||||
_avatar_url_cache[user_id] = url
|
_avatar_url_cache[user_id] = url
|
||||||
|
|
||||||
if len(_avatar_url_cache) > 10000:
|
if len(_avatar_url_cache) > 50000:
|
||||||
for _, key in zip(range(100), _avatar_url_cache):
|
for _, key in zip(range(100), _avatar_url_cache):
|
||||||
del _avatar_url_cache[key]
|
del _avatar_url_cache[key]
|
||||||
|
|
||||||
@ -96,7 +108,7 @@ class Room(blivedm.BLiveClient):
|
|||||||
})
|
})
|
||||||
|
|
||||||
async def _on_buy_guard(self, message: blivedm.GuardBuyMessage):
|
async def _on_buy_guard(self, message: blivedm.GuardBuyMessage):
|
||||||
self.send_message(Command.ADD_VIP, {
|
self.send_message(Command.ADD_MEMBER, {
|
||||||
'avatarUrl': await get_avatar_url(message.uid),
|
'avatarUrl': await get_avatar_url(message.uid),
|
||||||
'timestamp': message.start_time,
|
'timestamp': message.start_time,
|
||||||
'authorName': message.username
|
'authorName': message.username
|
||||||
@ -160,7 +172,7 @@ class RoomManager:
|
|||||||
text_data['authorType'] = 3
|
text_data['authorType'] = 3
|
||||||
text_data['content'] = "I can eat glass, it doesn't hurt me."
|
text_data['content'] = "I can eat glass, it doesn't hurt me."
|
||||||
room.send_message(Command.ADD_TEXT, text_data)
|
room.send_message(Command.ADD_TEXT, text_data)
|
||||||
room.send_message(Command.ADD_VIP, vip_data)
|
room.send_message(Command.ADD_MEMBER, vip_data)
|
||||||
room.send_message(Command.ADD_GIFT, gift_data)
|
room.send_message(Command.ADD_GIFT, gift_data)
|
||||||
gift_data['giftName'] = '节奏风暴'
|
gift_data['giftName'] = '节奏风暴'
|
||||||
gift_data['totalCoin'] = 100000
|
gift_data['totalCoin'] = 100000
|
||||||
|
Loading…
Reference in New Issue
Block a user