Create & Init Project...
This commit is contained in:
23
app/service/live/live-dm/BUILD
Normal file
23
app/service/live/live-dm/BUILD
Normal file
@ -0,0 +1,23 @@
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//app/service/live/live-dm/api/grpc:all-srcs",
|
||||
"//app/service/live/live-dm/cmd:all-srcs",
|
||||
"//app/service/live/live-dm/conf:all-srcs",
|
||||
"//app/service/live/live-dm/dao:all-srcs",
|
||||
"//app/service/live/live-dm/model:all-srcs",
|
||||
"//app/service/live/live-dm/server/grpc:all-srcs",
|
||||
"//app/service/live/live-dm/server/http:all-srcs",
|
||||
"//app/service/live/live-dm/service:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
34
app/service/live/live-dm/CHANGELOG.md
Normal file
34
app/service/live/live-dm/CHANGELOG.md
Normal file
@ -0,0 +1,34 @@
|
||||
# v1.0.0
|
||||
1. 上线功能xxx
|
||||
|
||||
# v1.1.3
|
||||
1. 添加保护
|
||||
2. 接入礼物弹幕
|
||||
|
||||
#v1.1.4
|
||||
1. databus 投递使用缓存队列
|
||||
2. 房管接口由liverpc迁移至grpc
|
||||
|
||||
#v1.1.5
|
||||
1. 短位号引起判断异常
|
||||
|
||||
#v1.1.6
|
||||
1. 弹幕后台配置迁移
|
||||
2. 去除弹幕广播http调用
|
||||
|
||||
#v1.1.7
|
||||
1. 弹幕统计透传弹幕类型
|
||||
|
||||
#v1.1.8
|
||||
1. 弹幕字 体大小限制
|
||||
2. \ \n / 非法字符限制
|
||||
|
||||
#v1.1.10
|
||||
1. 换行符号匹配
|
||||
|
||||
#v1.1.11
|
||||
1. databus 投递消息类型
|
||||
|
||||
#1.1.12
|
||||
1.2019拜年祭白名单
|
||||
2.弹幕配置迁移
|
6
app/service/live/live-dm/CONTRIBUTORS.md
Normal file
6
app/service/live/live-dm/CONTRIBUTORS.md
Normal file
@ -0,0 +1,6 @@
|
||||
# Owner
|
||||
yangbaibing
|
||||
|
||||
# Author
|
||||
|
||||
# Reviewer
|
10
app/service/live/live-dm/OWNERS
Normal file
10
app/service/live/live-dm/OWNERS
Normal file
@ -0,0 +1,10 @@
|
||||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
approvers:
|
||||
- yangbaibing
|
||||
labels:
|
||||
- live
|
||||
- service
|
||||
- service/live/live-dm
|
||||
options:
|
||||
no_parent_owners: true
|
12
app/service/live/live-dm/README.md
Normal file
12
app/service/live/live-dm/README.md
Normal file
@ -0,0 +1,12 @@
|
||||
# live-dm-service
|
||||
|
||||
# 项目简介
|
||||
1.
|
||||
|
||||
# 编译环境
|
||||
|
||||
|
||||
# 依赖包
|
||||
|
||||
|
||||
# 编译执行
|
23
app/service/live/live-dm/api/grpc/BUILD
Normal file
23
app/service/live/live-dm/api/grpc/BUILD
Normal file
@ -0,0 +1,23 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//app/service/live/live-dm/api/grpc/v1:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
62
app/service/live/live-dm/api/grpc/v1/BUILD
Normal file
62
app/service/live/live-dm/api/grpc/v1/BUILD
Normal file
@ -0,0 +1,62 @@
|
||||
load(
|
||||
"@io_bazel_rules_go//proto:def.bzl",
|
||||
"go_proto_library",
|
||||
)
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "v1_proto",
|
||||
srcs = ["api.proto"],
|
||||
tags = ["automanaged"],
|
||||
deps = ["@gogo_special_proto//github.com/gogo/protobuf/gogoproto"],
|
||||
)
|
||||
|
||||
go_proto_library(
|
||||
name = "v1_go_proto",
|
||||
compilers = ["@io_bazel_rules_go//proto:gogofast_grpc"],
|
||||
importpath = "go-common/app/service/live/live-dm/api/grpc/v1",
|
||||
proto = ":v1_proto",
|
||||
tags = ["automanaged"],
|
||||
deps = ["@com_github_gogo_protobuf//gogoproto:go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"api.bm.go",
|
||||
"client.go",
|
||||
],
|
||||
embed = [":v1_go_proto"],
|
||||
importpath = "go-common/app/service/live/live-dm/api/grpc/v1",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//library/net/http/blademaster:go_default_library",
|
||||
"//library/net/http/blademaster/binding:go_default_library",
|
||||
"//library/net/rpc/warden:go_default_library",
|
||||
"@com_github_gogo_protobuf//gogoproto:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@org_golang_google_grpc//:go_default_library",
|
||||
"@org_golang_x_net//context:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
67
app/service/live/live-dm/api/grpc/v1/api.bm.go
Normal file
67
app/service/live/live-dm/api/grpc/v1/api.bm.go
Normal file
@ -0,0 +1,67 @@
|
||||
// Code generated by protoc-gen-bm v0.1, DO NOT EDIT.
|
||||
// source: api/grpc/v1/api.proto
|
||||
|
||||
/*
|
||||
Package v1 is a generated blademaster stub package.
|
||||
This code was generated with go-common/app/tool/bmgen/protoc-gen-bm v0.1.
|
||||
|
||||
It is generated from these files:
|
||||
api/grpc/v1/api.proto
|
||||
*/
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
bm "go-common/library/net/http/blademaster"
|
||||
"go-common/library/net/http/blademaster/binding"
|
||||
)
|
||||
|
||||
// to suppressed 'imported but not used warning'
|
||||
var _ *bm.Context
|
||||
var _ context.Context
|
||||
var _ binding.StructValidator
|
||||
|
||||
// ============
|
||||
// DM Interface
|
||||
// ============
|
||||
|
||||
type DM interface {
|
||||
SendMsg(ctx context.Context, req *SendMsgReq) (resp *SendMsgResp, err error)
|
||||
|
||||
GetHistory(ctx context.Context, req *HistoryReq) (resp *HistoryResp, err error)
|
||||
}
|
||||
|
||||
var v1DMSvc DM
|
||||
|
||||
// @params SendMsgReq
|
||||
// @router GET /xlive/live-dm/v1/dM/SendMsg
|
||||
// @response SendMsgResp
|
||||
func dMSendMsg(c *bm.Context) {
|
||||
p := new(SendMsgReq)
|
||||
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
|
||||
return
|
||||
}
|
||||
resp, err := v1DMSvc.SendMsg(c, p)
|
||||
c.JSON(resp, err)
|
||||
}
|
||||
|
||||
// @params HistoryReq
|
||||
// @router GET /xlive/live-dm/v1/dM/GetHistory
|
||||
// @response HistoryResp
|
||||
func dMGetHistory(c *bm.Context) {
|
||||
p := new(HistoryReq)
|
||||
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
|
||||
return
|
||||
}
|
||||
resp, err := v1DMSvc.GetHistory(c, p)
|
||||
c.JSON(resp, err)
|
||||
}
|
||||
|
||||
// RegisterV1DMService Register the blademaster route with middleware map
|
||||
// midMap is the middleware map, the key is defined in proto
|
||||
func RegisterV1DMService(e *bm.Engine, svc DM, midMap map[string]bm.HandlerFunc) {
|
||||
v1DMSvc = svc
|
||||
e.GET("/xlive/live-dm/v1/dM/SendMsg", dMSendMsg)
|
||||
e.GET("/xlive/live-dm/v1/dM/GetHistory", dMGetHistory)
|
||||
}
|
65
app/service/live/live-dm/api/grpc/v1/api.dM.md
Normal file
65
app/service/live/live-dm/api/grpc/v1/api.dM.md
Normal file
@ -0,0 +1,65 @@
|
||||
##
|
||||
|
||||
`GET http://api.live.bilibili.com/xlive/live-dm/v1/dM/SendMsg`
|
||||
|
||||
### 请求参数
|
||||
|
||||
```json
|
||||
{
|
||||
"uid": 0,
|
||||
"roomid": 0,
|
||||
"msg": "",
|
||||
"rnd": "",
|
||||
"ip": "",
|
||||
"fontsize": 0,
|
||||
"mode": 0,
|
||||
"platform": "",
|
||||
"msgtype": 0,
|
||||
"bubble": 0,
|
||||
"lancer": {
|
||||
"buvid": "",
|
||||
"userAgent": "",
|
||||
"refer": "",
|
||||
"cookie": "",
|
||||
"build": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "ok",
|
||||
"data": {
|
||||
"islimit": true,
|
||||
"limitmsg": "",
|
||||
"code": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
##
|
||||
|
||||
`GET http://api.live.bilibili.com/xlive/live-dm/v1/dM/GetHistory`
|
||||
|
||||
### 请求参数
|
||||
|
||||
|参数名|必选|类型|描述|
|
||||
|:---|:---|:---|:---|
|
||||
|roomid|是|integer||
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "ok",
|
||||
"data": {
|
||||
"room": [
|
||||
""
|
||||
],
|
||||
"admin": [
|
||||
""
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
2056
app/service/live/live-dm/api/grpc/v1/api.pb.go
Normal file
2056
app/service/live/live-dm/api/grpc/v1/api.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
52
app/service/live/live-dm/api/grpc/v1/api.proto
Normal file
52
app/service/live/live-dm/api/grpc/v1/api.proto
Normal file
@ -0,0 +1,52 @@
|
||||
syntax = "proto3";
|
||||
package live.livedm.v1;
|
||||
option go_package = "v1";
|
||||
|
||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||
|
||||
|
||||
message SendMsgReq {
|
||||
int64 uid = 1 [(gogoproto.moretags) = 'form:"uid" validate:"required"'];
|
||||
int64 roomid = 2 [(gogoproto.moretags) = 'form:"roomid" validate:"required"'];
|
||||
string msg = 3 [(gogoproto.moretags) = 'form:"msg" validate:"required"'];
|
||||
string rnd = 4 [(gogoproto.moretags) = 'form:"rnd"'];
|
||||
string ip = 5 [(gogoproto.moretags) = 'form:"ip"'];
|
||||
int64 fontsize = 7 [(gogoproto.moretags) = 'form:"fontsize" validate:"gte=0"'];
|
||||
int64 mode = 8 [(gogoproto.moretags) = 'form:"mode" validate:"gte=0"'];
|
||||
string platform = 9 [(gogoproto.moretags) = 'form:"platform"'];
|
||||
int64 msgtype = 10 [(gogoproto.moretags) = 'form:"msgtype" validate:"gte=0"'];
|
||||
int64 bubble = 11 [(gogoproto.moretags) = 'form:"bubble"'];
|
||||
lancer lancer = 12 [(gogoproto.moretags) = 'form:"lancer"'];
|
||||
}
|
||||
|
||||
message lancer {
|
||||
string buvid = 1 [(gogoproto.moretags) = 'form:"buvid"'];
|
||||
string userAgent = 2 [(gogoproto.moretags) = 'form:"userAgent"'];
|
||||
string refer = 3 [(gogoproto.moretags) = 'form:"refer"'];
|
||||
string cookie = 4 [(gogoproto.moretags) = 'form:"cookie"'];
|
||||
int64 build = 5 [(gogoproto.moretags) = 'form:"build"'];
|
||||
}
|
||||
|
||||
message SendMsgResp {
|
||||
bool isLimit = 1 [(gogoproto.jsontag) = "islimit"];
|
||||
string limitMsg = 2 [(gogoproto.jsontag) = "limitmsg"];
|
||||
int32 code = 3 [(gogoproto.jsontag) = "code"];
|
||||
}
|
||||
|
||||
message HistoryReq {
|
||||
int64 roomid = 1 [(gogoproto.moretags) = 'form:"roomid" validate:"required"'];
|
||||
}
|
||||
|
||||
message HistoryResp{
|
||||
repeated string room = 1 [(gogoproto.jsontag) = "room"];
|
||||
repeated string admin = 2 [(gogoproto.jsontag) = "admin"];
|
||||
}
|
||||
|
||||
message ErrMsg {
|
||||
string message =1;
|
||||
}
|
||||
|
||||
service DM {
|
||||
rpc SendMsg(SendMsgReq) returns (SendMsgResp);
|
||||
rpc GetHistory(HistoryReq) returns (HistoryResp);
|
||||
}
|
23
app/service/live/live-dm/api/grpc/v1/client.go
Normal file
23
app/service/live/live-dm/api/grpc/v1/client.go
Normal file
@ -0,0 +1,23 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/library/net/rpc/warden"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
//AppID 弹幕服务discoverID
|
||||
const AppID = "live.livedm"
|
||||
|
||||
//NewClient 弹幕服务client创建
|
||||
func NewClient(cfg *warden.ClientConfig, opts ...grpc.DialOption) (DMClient, error) {
|
||||
client := warden.NewClient(cfg, opts...)
|
||||
conn, err := client.Dial(context.Background(), "discovery://default/"+AppID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewDMClient(conn), nil
|
||||
}
|
1
app/service/live/live-dm/api/http/api.md
Normal file
1
app/service/live/live-dm/api/http/api.md
Normal file
@ -0,0 +1 @@
|
||||
# HTTP API文档
|
27
app/service/live/live-dm/api/http/v1/dM.md
Normal file
27
app/service/live/live-dm/api/http/v1/dM.md
Normal file
@ -0,0 +1,27 @@
|
||||
##
|
||||
|
||||
`GET http://api.live.bilibili.com/xlive/dm/v1/dM/SendMsg`
|
||||
|
||||
### 请求参数
|
||||
|
||||
|参数名|必选|类型|描述|
|
||||
|:---|:---|:---|:---|
|
||||
|uid|否|integer||
|
||||
|roomid|否|integer||
|
||||
|msg|否|string||
|
||||
|rnd|否|integer||
|
||||
|ip|否|string||
|
||||
|fontsize|否|integer||
|
||||
|mode|否|integer||
|
||||
|platform|否|string||
|
||||
|msgtype|否|integer||
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "ok",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
45
app/service/live/live-dm/cmd/BUILD
Normal file
45
app/service/live/live-dm/cmd/BUILD
Normal file
@ -0,0 +1,45 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "cmd",
|
||||
embed = [":go_default_library"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["main.go"],
|
||||
data = ["test.toml"],
|
||||
importpath = "go-common/app/service/live/live-dm/cmd",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/service/live/live-dm/conf:go_default_library",
|
||||
"//app/service/live/live-dm/server/grpc:go_default_library",
|
||||
"//app/service/live/live-dm/server/http:go_default_library",
|
||||
"//app/service/live/live-dm/service:go_default_library",
|
||||
"//library/ecode/tip:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
"//library/net/trace:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
49
app/service/live/live-dm/cmd/main.go
Normal file
49
app/service/live/live-dm/cmd/main.go
Normal file
@ -0,0 +1,49 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
"go-common/app/service/live/live-dm/server/grpc"
|
||||
"go-common/app/service/live/live-dm/server/http"
|
||||
"go-common/app/service/live/live-dm/service"
|
||||
ecode "go-common/library/ecode/tip"
|
||||
"go-common/library/log"
|
||||
"go-common/library/net/trace"
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if err := conf.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
log.Init(conf.Conf.Log)
|
||||
defer log.Close()
|
||||
log.Info("dm-service start")
|
||||
trace.Init(conf.Conf.Tracer)
|
||||
defer trace.Close()
|
||||
ecode.Init(conf.Conf.Ecode)
|
||||
svc := service.New(conf.Conf)
|
||||
grpc.Init(conf.Conf)
|
||||
http.Init(conf.Conf)
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
|
||||
for {
|
||||
s := <-c
|
||||
log.Info("get a signal %s", s.String())
|
||||
switch s {
|
||||
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
|
||||
svc.Close()
|
||||
log.Info("dm-service exit")
|
||||
time.Sleep(time.Second)
|
||||
return
|
||||
case syscall.SIGHUP:
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
118
app/service/live/live-dm/cmd/test.toml
Normal file
118
app/service/live/live-dm/cmd/test.toml
Normal file
@ -0,0 +1,118 @@
|
||||
[HTTPClient]
|
||||
key = "e7482d29be4a95b8"
|
||||
secret = "9e803791cdef756e75faee68e12b7442"
|
||||
dial = "100ms"
|
||||
timeout = "5s"
|
||||
keepAlive = "60s"
|
||||
[HTTPClient.breaker]
|
||||
window = "3s"
|
||||
sleep = "100ms"
|
||||
bucket = 10
|
||||
ratio = 0.5
|
||||
request = 100
|
||||
[Redis]
|
||||
name = "dm-service"
|
||||
proto = "tcp"
|
||||
addr = "172.18.33.171:6379"
|
||||
idle = 10
|
||||
active = 10
|
||||
dialTimeout = "1s"
|
||||
readTimeout = "1s"
|
||||
writeTimeout = "1s"
|
||||
idleTimeout = "10s"
|
||||
expire = "1m"
|
||||
|
||||
|
||||
[WhiteListRedis]
|
||||
name = "dm-service"
|
||||
proto = "tcp"
|
||||
addr = "172.16.38.166:10028"
|
||||
idle = 10
|
||||
active = 10
|
||||
dialTimeout = "1s"
|
||||
readTimeout = "1s"
|
||||
writeTimeout = "1s"
|
||||
idleTimeout = "10s"
|
||||
expire = "1m"
|
||||
|
||||
[BNJRoomList]
|
||||
544641 = true
|
||||
2233 = true
|
||||
|
||||
[BNDatabus]
|
||||
key = "ec4c0820d525d67b"
|
||||
secret = "e20f8f664bf10722efeb6aac0cc16011"
|
||||
group = "LiveDanmuSend-LiveLive-P"
|
||||
topic = "LiveDanmuSend-T"
|
||||
action = "pub"
|
||||
buffer = 128
|
||||
name = "live-dm/databus"
|
||||
proto = "tcp"
|
||||
addr = "172.16.33.50:6205"
|
||||
active = 1
|
||||
idle = 1
|
||||
dialTimeout = "1s"
|
||||
readTimeout = "1s"
|
||||
writeTimeout = "1s"
|
||||
idleTimeout = "10s"
|
||||
|
||||
[CacheDatabus]
|
||||
Size = 1024
|
||||
|
||||
[LiveRPC.bannedService]
|
||||
AppID = "live.bannedservice"
|
||||
ConnTimeout = "50ms"
|
||||
[LiveRPC.room]
|
||||
AppID = "live.room"
|
||||
ConnTimeout = "50ms"
|
||||
[LiveRPC.liveUser]
|
||||
AppID = "live.liveuser"
|
||||
ConnTimeout = "50ms"
|
||||
[LiveRPC.activity]
|
||||
AppID = "live.activity"
|
||||
ConnTimeout = "50ms"
|
||||
[LiveRPC.avService]
|
||||
AppID = "live.av"
|
||||
ConnTimeout = "50ms"
|
||||
[LiveRPC.fansMedal]
|
||||
AppID = "live.fansmedal"
|
||||
ConnTimeout = "50ms"
|
||||
[LiveRPC.rc]
|
||||
AppID = "live.rc"
|
||||
ConnTimeout = "50ms"
|
||||
[LiveRPC.rankdbService]
|
||||
AppID = "live.rankdb"
|
||||
ConnTimeout = "50ms"
|
||||
[LiveRPC.userext]
|
||||
AppID = "live.userext"
|
||||
ConnTimeout = "50ms"
|
||||
[LiveRPC.user]
|
||||
AppID = "live.user"
|
||||
ConnTimeout = "50ms"
|
||||
|
||||
|
||||
[DmRules]
|
||||
AreaLimit = false
|
||||
RealName = false
|
||||
PhoneLimit = true
|
||||
AllUserLimit = false
|
||||
LevelLimitStatus = false
|
||||
LevelLimit = -1
|
||||
MsgLength = 20
|
||||
DmNum = 20
|
||||
DMPercent = 25
|
||||
[DmRules.Nixiang]
|
||||
[DmRules.Color]
|
||||
|
||||
|
||||
[Lancer.DMsend]
|
||||
taskID = "000582"
|
||||
proto = "tcp"
|
||||
addr = "172.18.33.124:15140"
|
||||
chanSize = 10240
|
||||
|
||||
[Lancer.DMErr]
|
||||
taskID = "001409"
|
||||
proto = "tcp"
|
||||
addr = "172.18.33.124:15140"
|
||||
chanSize = 10240
|
44
app/service/live/live-dm/conf/BUILD
Normal file
44
app/service/live/live-dm/conf/BUILD
Normal file
@ -0,0 +1,44 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["conf.go"],
|
||||
importpath = "go-common/app/service/live/live-dm/conf",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//library/cache/memcache:go_default_library",
|
||||
"//library/cache/redis:go_default_library",
|
||||
"//library/conf:go_default_library",
|
||||
"//library/database/sql:go_default_library",
|
||||
"//library/ecode/tip:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
"//library/log/infoc:go_default_library",
|
||||
"//library/net/http/blademaster:go_default_library",
|
||||
"//library/net/http/blademaster/middleware/verify:go_default_library",
|
||||
"//library/net/rpc/liverpc:go_default_library",
|
||||
"//library/net/rpc/warden:go_default_library",
|
||||
"//library/net/trace:go_default_library",
|
||||
"//library/queue/databus:go_default_library",
|
||||
"//vendor/github.com/BurntSushi/toml:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
133
app/service/live/live-dm/conf/conf.go
Normal file
133
app/service/live/live-dm/conf/conf.go
Normal file
@ -0,0 +1,133 @@
|
||||
package conf
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
|
||||
"go-common/library/cache/memcache"
|
||||
"go-common/library/cache/redis"
|
||||
"go-common/library/conf"
|
||||
"go-common/library/database/sql"
|
||||
ecode "go-common/library/ecode/tip"
|
||||
"go-common/library/log"
|
||||
"go-common/library/log/infoc"
|
||||
bm "go-common/library/net/http/blademaster"
|
||||
"go-common/library/net/http/blademaster/middleware/verify"
|
||||
"go-common/library/net/rpc/liverpc"
|
||||
"go-common/library/net/rpc/warden"
|
||||
"go-common/library/net/trace"
|
||||
"go-common/library/queue/databus"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
var (
|
||||
confPath string
|
||||
client *conf.Client
|
||||
// Conf config
|
||||
Conf = &Config{}
|
||||
)
|
||||
|
||||
// Config .
|
||||
type Config struct {
|
||||
Log *log.Config
|
||||
BM *bm.ServerConfig
|
||||
Verify *verify.Config
|
||||
Tracer *trace.Config
|
||||
Redis *redis.Config
|
||||
WhiteListRedis *redis.Config
|
||||
Memcache *memcache.Config
|
||||
MySQL *sql.Config
|
||||
Ecode *ecode.Config
|
||||
DmRules *dmRules
|
||||
FilterClient *warden.ClientConfig
|
||||
AccClient *warden.ClientConfig
|
||||
XuserClent *warden.ClientConfig
|
||||
LocationClient *warden.ClientConfig
|
||||
SpyClient *warden.ClientConfig
|
||||
BcastClient *warden.ClientConfig
|
||||
UExpClient *warden.ClientConfig
|
||||
IsAdminClient *warden.ClientConfig
|
||||
HTTPClient *bm.ClientConfig
|
||||
LiveRPC map[string]*liverpc.ClientConfig
|
||||
BNDatabus *databus.Config
|
||||
Lancer *lancer
|
||||
CacheDatabus *cache
|
||||
BNJRoomList map[string]bool
|
||||
}
|
||||
|
||||
type cache struct {
|
||||
Size int
|
||||
}
|
||||
|
||||
type lancer struct {
|
||||
DMErr *infoc.Config
|
||||
DMSend *infoc.Config
|
||||
}
|
||||
|
||||
type dmRules struct {
|
||||
AllUserLimit bool
|
||||
AreaLimit bool
|
||||
LevelLimitStatus bool
|
||||
LevelLimit int64
|
||||
PhoneLimit bool
|
||||
RealName bool
|
||||
MsgLength int
|
||||
DmNum int64
|
||||
DmPercent int64
|
||||
Nixiang map[string]bool
|
||||
Color map[string]int64
|
||||
DMwhitelist bool
|
||||
DMwhiteListID string
|
||||
}
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&confPath, "conf", "", "default config path")
|
||||
}
|
||||
|
||||
// Init init conf
|
||||
func Init() error {
|
||||
if confPath != "" {
|
||||
return local()
|
||||
}
|
||||
return remote()
|
||||
}
|
||||
|
||||
func local() (err error) {
|
||||
_, err = toml.DecodeFile(confPath, &Conf)
|
||||
return
|
||||
}
|
||||
|
||||
func remote() (err error) {
|
||||
if client, err = conf.New(); err != nil {
|
||||
return
|
||||
}
|
||||
if err = load(); err != nil {
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
for range client.Event() {
|
||||
log.Info("config reload")
|
||||
if load() != nil {
|
||||
log.Error("config reload error (%v)", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
return
|
||||
}
|
||||
|
||||
func load() (err error) {
|
||||
var (
|
||||
s string
|
||||
ok bool
|
||||
tmpConf *Config
|
||||
)
|
||||
if s, ok = client.Toml2(); !ok {
|
||||
return errors.New("load config center error")
|
||||
}
|
||||
if _, err = toml.Decode(s, &tmpConf); err != nil {
|
||||
return errors.New("could not decode config")
|
||||
}
|
||||
*Conf = *tmpConf
|
||||
return
|
||||
}
|
110
app/service/live/live-dm/dao/BUILD
Normal file
110
app/service/live/live-dm/dao/BUILD
Normal file
@ -0,0 +1,110 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"dao.go",
|
||||
"data.go",
|
||||
"getCheckInfo.go",
|
||||
"getDMConf.go",
|
||||
"gethistory.go",
|
||||
"grpc.go",
|
||||
"ipdb.go",
|
||||
"liveRPC.go",
|
||||
"ratelimit.go",
|
||||
"send.go",
|
||||
"white_list.go",
|
||||
],
|
||||
importpath = "go-common/app/service/live/live-dm/dao",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/service/live/activity/api/liverpc:go_default_library",
|
||||
"//app/service/live/activity/api/liverpc/v1:go_default_library",
|
||||
"//app/service/live/av/api/liverpc:go_default_library",
|
||||
"//app/service/live/banned_service/api/liverpc:go_default_library",
|
||||
"//app/service/live/broadcast-proxy/api/v1:go_default_library",
|
||||
"//app/service/live/fans_medal/api/liverpc:go_default_library",
|
||||
"//app/service/live/fans_medal/api/liverpc/v2:go_default_library",
|
||||
"//app/service/live/live-dm/conf:go_default_library",
|
||||
"//app/service/live/live-dm/model:go_default_library",
|
||||
"//app/service/live/live_user/api/liverpc:go_default_library",
|
||||
"//app/service/live/live_user/api/liverpc/v1:go_default_library",
|
||||
"//app/service/live/rankdb/api/liverpc:go_default_library",
|
||||
"//app/service/live/rankdb/api/liverpc/v1:go_default_library",
|
||||
"//app/service/live/rc/api/liverpc:go_default_library",
|
||||
"//app/service/live/rc/api/liverpc/v1:go_default_library",
|
||||
"//app/service/live/resource/sdk:go_default_library",
|
||||
"//app/service/live/room/api/liverpc:go_default_library",
|
||||
"//app/service/live/room/api/liverpc/v1:go_default_library",
|
||||
"//app/service/live/room/api/liverpc/v2:go_default_library",
|
||||
"//app/service/live/third_api/liveBroadcast:go_default_library",
|
||||
"//app/service/live/user/api/liverpc:go_default_library",
|
||||
"//app/service/live/user/api/liverpc/v3:go_default_library",
|
||||
"//app/service/live/userext/api/liverpc:go_default_library",
|
||||
"//app/service/live/userext/api/liverpc/v1:go_default_library",
|
||||
"//app/service/live/xuser/api/grpc/v1:go_default_library",
|
||||
"//app/service/main/account/api:go_default_library",
|
||||
"//app/service/main/filter/api/grpc/v1:go_default_library",
|
||||
"//app/service/main/location/api:go_default_library",
|
||||
"//app/service/main/spy/api:go_default_library",
|
||||
"//library/cache/redis:go_default_library",
|
||||
"//library/ecode:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
"//library/log/infoc:go_default_library",
|
||||
"//library/net/rpc/liverpc:go_default_library",
|
||||
"//library/net/rpc/warden:go_default_library",
|
||||
"//library/queue/databus:go_default_library",
|
||||
"//library/sync/pipeline/fanout:go_default_library",
|
||||
"//vendor/github.com/ipipdotnet/ipdb-go:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"@org_golang_google_grpc//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"getCheckInfo_test.go",
|
||||
"getDMConf_test.go",
|
||||
"ratelimit_test.go",
|
||||
"send_test.go",
|
||||
"white_list_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//app/service/live/activity/api/liverpc:go_default_library",
|
||||
"//app/service/live/fans_medal/api/liverpc:go_default_library",
|
||||
"//app/service/live/live-dm/conf:go_default_library",
|
||||
"//app/service/live/live_user/api/liverpc:go_default_library",
|
||||
"//app/service/live/rankdb/api/liverpc:go_default_library",
|
||||
"//app/service/live/rc/api/liverpc:go_default_library",
|
||||
"//app/service/live/room/api/liverpc:go_default_library",
|
||||
"//app/service/live/userext/api/liverpc:go_default_library",
|
||||
"//app/service/main/account/api:go_default_library",
|
||||
"//app/service/main/filter/api/grpc/v1:go_default_library",
|
||||
"//app/service/main/spy/api:go_default_library",
|
||||
"//library/net/metadata:go_default_library",
|
||||
],
|
||||
)
|
41
app/service/live/live-dm/dao/dao.go
Normal file
41
app/service/live/live-dm/dao/dao.go
Normal file
@ -0,0 +1,41 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
"go-common/library/cache/redis"
|
||||
"go-common/library/sync/pipeline/fanout"
|
||||
)
|
||||
|
||||
// Dao dao
|
||||
type Dao struct {
|
||||
c *conf.Config
|
||||
redis *redis.Pool
|
||||
whitelistredis *redis.Pool
|
||||
Databus *fanout.Fanout
|
||||
}
|
||||
|
||||
// New init mysql db
|
||||
func New(c *conf.Config) (dao *Dao) {
|
||||
dao = &Dao{
|
||||
c: c,
|
||||
redis: redis.NewPool(c.Redis),
|
||||
whitelistredis: redis.NewPool(c.WhiteListRedis),
|
||||
Databus: fanout.New("dmDatabus", fanout.Worker(1), fanout.Buffer(c.CacheDatabus.Size)),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Close close the resource.
|
||||
func (d *Dao) Close() {
|
||||
d.redis.Close()
|
||||
d.Databus.Close()
|
||||
d.whitelistredis.Close()
|
||||
}
|
||||
|
||||
// Ping dao ping
|
||||
func (d *Dao) Ping(c context.Context) error {
|
||||
// TODO: redis
|
||||
return nil
|
||||
}
|
84
app/service/live/live-dm/dao/data.go
Normal file
84
app/service/live/live-dm/dao/data.go
Normal file
@ -0,0 +1,84 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
titansSdk "go-common/app/service/live/resource/sdk"
|
||||
"go-common/library/log"
|
||||
"go-common/library/log/infoc"
|
||||
"go-common/library/queue/databus"
|
||||
)
|
||||
|
||||
var (
|
||||
//拜年祭投递databus
|
||||
bndatabus *databus.Databus
|
||||
//InfocDMSend 弹幕发送成功上报
|
||||
InfocDMSend *infoc.Infoc
|
||||
//InfocDMErr 弹幕发送失败上报
|
||||
InfocDMErr *infoc.Infoc
|
||||
)
|
||||
|
||||
//InitDatabus 初始化databus
|
||||
func InitDatabus(c *conf.Config) {
|
||||
bndatabus = databus.New(c.BNDatabus)
|
||||
}
|
||||
|
||||
//InitLancer 初始化lancer上报
|
||||
func InitLancer(c *conf.Config) {
|
||||
InfocDMErr = infoc.New(c.Lancer.DMErr)
|
||||
InfocDMSend = infoc.New(c.Lancer.DMSend)
|
||||
}
|
||||
|
||||
//InitTitan 初始化kv配置
|
||||
func InitTitan() {
|
||||
conf := &titansSdk.Config{
|
||||
TreeId: 72389,
|
||||
Expire: 1,
|
||||
}
|
||||
titansSdk.Init(conf)
|
||||
}
|
||||
|
||||
//LimitConf 弹幕限制配置
|
||||
type LimitConf struct {
|
||||
AreaLimit bool `json:"areaLimit"`
|
||||
AllUserLimit bool `json:"AllUserLimit"`
|
||||
LevelLimitStatus bool `json:"LevelLimitStatus"`
|
||||
LevelLimit int64 `json:"LevelLimit"`
|
||||
RealName bool `json:"RealName"`
|
||||
PhoneLimit bool `json:"PhoneLimit"`
|
||||
MsgLength int `json:"MsgLength"`
|
||||
DmNum int64 `json:"DmNum"`
|
||||
DMPercent int64 `json:"DMPercent"`
|
||||
DMwhitelist bool `json:"DMwhitelist"`
|
||||
DMwhitelistID string `json:"DMwhitelistID"`
|
||||
}
|
||||
|
||||
//GetDMCheckConf 获取弹幕配置参数
|
||||
func (l *LimitConf) GetDMCheckConf() {
|
||||
|
||||
cf, err := titansSdk.Get("dmLimit")
|
||||
if err != nil {
|
||||
log.Error("DM: get conf err:%+v", err)
|
||||
return
|
||||
}
|
||||
|
||||
conf := &LimitConf{}
|
||||
err = json.Unmarshal([]byte(cf), conf)
|
||||
if err != nil {
|
||||
log.Error("DM: decode conf jsons err:%+v conf:%s", err, cf)
|
||||
return
|
||||
}
|
||||
|
||||
l.AreaLimit = conf.AreaLimit
|
||||
l.AllUserLimit = conf.AllUserLimit
|
||||
l.LevelLimitStatus = conf.LevelLimitStatus
|
||||
l.LevelLimit = conf.LevelLimit
|
||||
l.RealName = conf.RealName
|
||||
l.PhoneLimit = conf.PhoneLimit
|
||||
l.DmNum = conf.DmNum
|
||||
l.DMwhitelist = conf.DMwhitelist
|
||||
l.DMPercent = conf.DMPercent
|
||||
l.MsgLength = conf.MsgLength
|
||||
l.DMwhitelistID = conf.DMwhitelistID
|
||||
|
||||
}
|
391
app/service/live/live-dm/dao/getCheckInfo.go
Normal file
391
app/service/live/live-dm/dao/getCheckInfo.go
Normal file
@ -0,0 +1,391 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
fansMedalService "go-common/app/service/live/fans_medal/api/liverpc/v2"
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
liveUserService "go-common/app/service/live/live_user/api/liverpc/v1"
|
||||
roomService "go-common/app/service/live/room/api/liverpc/v2"
|
||||
userService "go-common/app/service/live/user/api/liverpc/v3"
|
||||
userextService "go-common/app/service/live/userext/api/liverpc/v1"
|
||||
xuserService "go-common/app/service/live/xuser/api/grpc/v1"
|
||||
acctountService "go-common/app/service/main/account/api"
|
||||
filterService "go-common/app/service/main/filter/api/grpc/v1"
|
||||
spyService "go-common/app/service/main/spy/api"
|
||||
"go-common/library/log"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
//UserInfo 用户等级,经验等信息
|
||||
type UserInfo struct {
|
||||
Vip int
|
||||
Svip int
|
||||
UserLever int64
|
||||
UserScore int64
|
||||
ULevelRank int64
|
||||
ULevelColor int64
|
||||
UnameColor string
|
||||
RoomAdmin bool
|
||||
PrivilegeType int
|
||||
Bubble int64
|
||||
MedalInfo *FansMedalInfo
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
//UserScore 用户真实分已经弹幕ai分
|
||||
type UserScore struct {
|
||||
UserScore int64
|
||||
MsgAI int64
|
||||
MsgLevel int64
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
//DMConf 弹幕配置
|
||||
type DMConf struct {
|
||||
Mode int64
|
||||
Color int64
|
||||
Length int64
|
||||
}
|
||||
|
||||
//FansMedalInfo 粉丝勋章信息
|
||||
type FansMedalInfo struct {
|
||||
MedalID int64
|
||||
RUID int64
|
||||
RUName string
|
||||
MedalLevel int64
|
||||
MedalName string
|
||||
AnchorName string
|
||||
RoomID int64
|
||||
MColor int64
|
||||
SpecialMedal string
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
//RoomConf 播主房间配置信息
|
||||
type RoomConf struct {
|
||||
UID int64
|
||||
RoomShield int64
|
||||
RoomID int64
|
||||
Anchor string
|
||||
}
|
||||
|
||||
//UserBindInfo 用户手机,实名等信息
|
||||
type UserBindInfo struct {
|
||||
Identification int32
|
||||
MobileVerify int32
|
||||
Uname string
|
||||
URank int32
|
||||
// MobileVirtual int64 无虚拟号段信息
|
||||
}
|
||||
|
||||
//Get 获取用户的弹幕配置信息
|
||||
func (d *DMConf) Get(ctx context.Context, uid int64, roomid int64, c *conf.Config) error {
|
||||
req := &userextService.DanmuConfGetAllReq{
|
||||
Uid: uid,
|
||||
Roomid: roomid,
|
||||
}
|
||||
resp, err := UserExtServiceClient.V1DanmuConf.GetAll(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: userextService GetAll err: %v", err)
|
||||
}
|
||||
d.Color = 16777215
|
||||
d.Mode = 1
|
||||
d.Length = 20
|
||||
return nil
|
||||
}
|
||||
if resp.Code != 0 {
|
||||
log.Error("DM: userextService GetAll err code: %d", resp.Code)
|
||||
d.Color = 16777215
|
||||
d.Mode = 1
|
||||
d.Length = 20
|
||||
return nil
|
||||
}
|
||||
d.Color = resp.Data.Color
|
||||
d.Mode = resp.Data.Mode
|
||||
d.Length = resp.Data.Length
|
||||
su := strconv.FormatInt(uid, 10)
|
||||
if c.DmRules.Nixiang[su] {
|
||||
d.Mode = 6
|
||||
}
|
||||
if c.DmRules.Color[su] != 0 {
|
||||
d.Color = c.DmRules.Color[su]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get 获取用户等级,经验等信息
|
||||
func (u *UserInfo) Get(ctx context.Context, uid int64) error {
|
||||
req := &userService.UserGetUserLevelInfoReq{
|
||||
Uid: uid,
|
||||
}
|
||||
resp, err := userClient.V3User.GetUserLevelInfo(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: user err: %v", err)
|
||||
}
|
||||
u.lock.Lock()
|
||||
u.UserLever = 0
|
||||
u.UserScore = 0
|
||||
u.ULevelColor = 16752445
|
||||
u.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
if resp.Code != 0 {
|
||||
log.Error("DM: user GetUserLevelInfo err code: %d", resp.Code)
|
||||
u.lock.Lock()
|
||||
u.UserLever = 0
|
||||
u.UserScore = 0
|
||||
u.ULevelColor = 16752445
|
||||
u.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
u.lock.Lock()
|
||||
u.UserLever = resp.Data.Level
|
||||
u.UserScore = resp.Data.Exp
|
||||
u.ULevelColor = resp.Data.Color
|
||||
u.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
//GetVipInfo 获取用户的老爷等级
|
||||
func (u *UserInfo) GetVipInfo(ctx context.Context, uid int64) error {
|
||||
req := &xuserService.UidReq{
|
||||
Uid: uid,
|
||||
}
|
||||
resp, err := vipCli.Info(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: xuserService get vip Info err: %v", err)
|
||||
}
|
||||
u.lock.Lock()
|
||||
u.Vip = 0
|
||||
u.Svip = 0
|
||||
u.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
u.lock.Lock()
|
||||
u.Vip = resp.Info.Vip
|
||||
u.Svip = resp.Info.Svip
|
||||
u.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
//GetPrivilegeType 获取大航海信息
|
||||
func (u *UserInfo) GetPrivilegeType(ctx context.Context, uid int64, ruid int64) error {
|
||||
req := &liveUserService.GuardGetByUidTargetIdReq{
|
||||
Uid: uid,
|
||||
TargetId: ruid,
|
||||
IsLimitOne: 0,
|
||||
}
|
||||
resp, err := LiveUserServiceClient.V1Guard.GetByUidTargetId(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: liveUserService GetByUidTargetId err: %v", err)
|
||||
}
|
||||
u.lock.Lock()
|
||||
u.PrivilegeType = 0
|
||||
u.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
if resp.Code != 0 {
|
||||
log.Error("DM: liveUserService GetByUidTargetId err code: %d", resp.Code)
|
||||
u.lock.Lock()
|
||||
u.PrivilegeType = 0
|
||||
u.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
var PrivilegeType int64
|
||||
for _, val := range resp.Data {
|
||||
i := val.PrivilegeType
|
||||
if PrivilegeType == 0 {
|
||||
PrivilegeType = i
|
||||
}
|
||||
if PrivilegeType != 0 && PrivilegeType > i {
|
||||
PrivilegeType = i
|
||||
}
|
||||
}
|
||||
u.lock.Lock()
|
||||
u.PrivilegeType = int(PrivilegeType)
|
||||
u.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
//IsRoomAdmin 判断用户是否是房管
|
||||
func (u *UserInfo) IsRoomAdmin(ctx context.Context, uid int64, roomid int64) error {
|
||||
defer u.lock.Unlock()
|
||||
if roomid == 59125 || roomid == 5440 {
|
||||
u.lock.Lock()
|
||||
u.RoomAdmin = false
|
||||
return nil
|
||||
}
|
||||
|
||||
req := &xuserService.RoomAdminIsAdminShortReq{
|
||||
Uid: uid,
|
||||
Roomid: roomid,
|
||||
}
|
||||
resp, err := isAdmin.IsAdminShort(ctx, req)
|
||||
if err != nil {
|
||||
log.Error("DM: xuser IsAdminShort err: %+v", err)
|
||||
u.lock.Lock()
|
||||
u.RoomAdmin = false
|
||||
return nil
|
||||
}
|
||||
if resp.Result == 1 {
|
||||
u.lock.Lock()
|
||||
u.RoomAdmin = true
|
||||
return nil
|
||||
}
|
||||
|
||||
u.lock.Lock()
|
||||
u.RoomAdmin = false
|
||||
return nil
|
||||
}
|
||||
|
||||
//GetFansMedal 获取主播的粉丝勋章信息
|
||||
func (f *FansMedalInfo) GetFansMedal(ctx context.Context, uid int64) error {
|
||||
req := &fansMedalService.HighQpsLiveWearedReq{
|
||||
Uid: uid,
|
||||
}
|
||||
resq, err := FansMedalServiceClient.V2HighQps.LiveWeared(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: fansMedalService LiveWeared err: %v", err)
|
||||
}
|
||||
f.RUID = 0
|
||||
f.MedalLevel = 1
|
||||
f.MedalName = ""
|
||||
f.MColor = 0
|
||||
return nil
|
||||
}
|
||||
if resq.Code != 0 {
|
||||
log.Error("DM: fansMedalService LiveWeared err code: %d", resq.Code)
|
||||
f.RUID = 0
|
||||
f.MedalLevel = 1
|
||||
f.MedalName = ""
|
||||
f.MColor = 0
|
||||
return nil
|
||||
}
|
||||
f.RUID = resq.Data.TargetId
|
||||
f.MedalLevel = resq.Data.Level
|
||||
f.MedalName = resq.Data.MedalName
|
||||
f.MColor = resq.Data.MedalColor
|
||||
return nil
|
||||
}
|
||||
|
||||
//Get 获取主播房间配置信息s
|
||||
func (r *RoomConf) Get(ctx context.Context, roomID int64) error {
|
||||
req := &roomService.RoomGetByIdsReq{
|
||||
Ids: []int64{roomID},
|
||||
}
|
||||
resp, err := RoomServiceClient.V2Room.GetByIds(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: roomService GetByIds err: %v", err)
|
||||
}
|
||||
r.RoomID = roomID
|
||||
r.UID = 0
|
||||
r.RoomShield = 0
|
||||
r.Anchor = ""
|
||||
return nil
|
||||
}
|
||||
if resp.Code != 0 {
|
||||
log.Error("DM: roomService GetByIds err code: %d", resp.Code)
|
||||
r.RoomID = roomID
|
||||
r.UID = 0
|
||||
r.RoomShield = 0
|
||||
r.Anchor = ""
|
||||
return nil
|
||||
}
|
||||
if _, ok := resp.Data[roomID]; !ok {
|
||||
log.Error("DM: roomService GetByIds error roomid:%d", roomID)
|
||||
r.RoomID = roomID
|
||||
r.UID = 0
|
||||
r.RoomShield = 0
|
||||
r.Anchor = ""
|
||||
return nil
|
||||
}
|
||||
r.RoomID = resp.Data[roomID].Roomid
|
||||
r.UID = resp.Data[roomID].Uid
|
||||
r.RoomShield = resp.Data[roomID].RoomShield
|
||||
r.Anchor = resp.Data[roomID].Uname
|
||||
return nil
|
||||
}
|
||||
|
||||
//Get 获取用户绑定信息,实名认知,绑定手机等信息
|
||||
func (u *UserBindInfo) Get(ctx context.Context, uid int64) error {
|
||||
req := &acctountService.MidReq{
|
||||
Mid: uid,
|
||||
}
|
||||
resp, err := ac.Profile3(ctx, req)
|
||||
if err != nil {
|
||||
log.Error("DM: acctountService Profile3 err: %v", err)
|
||||
u.Identification = 0
|
||||
u.MobileVerify = 0
|
||||
u.Uname = ""
|
||||
u.URank = 0
|
||||
return nil
|
||||
}
|
||||
u.Identification = resp.Profile.Identification
|
||||
u.MobileVerify = resp.Profile.TelStatus
|
||||
u.Uname = resp.Profile.Name
|
||||
u.URank = resp.Profile.Rank
|
||||
return nil
|
||||
}
|
||||
|
||||
//GetUserScore 用户真实分
|
||||
func (u *UserScore) GetUserScore(ctx context.Context, uid int64) error {
|
||||
req := &spyService.InfoReq{
|
||||
Mid: uid,
|
||||
}
|
||||
resp, err := SpyClient.Info(ctx, req)
|
||||
if err != nil {
|
||||
log.Error("DM: 获取用户真实分错误 err: %v", err)
|
||||
u.lock.Lock()
|
||||
u.UserScore = 0
|
||||
u.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
u.lock.Lock()
|
||||
u.UserScore = int64(resp.Ui.Score)
|
||||
u.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
//GetMsgScore 获取弹幕AI分
|
||||
func (u *UserScore) GetMsgScore(ctx context.Context, msg string) error {
|
||||
req := &filterService.FilterReq{
|
||||
Area: "live_danmu",
|
||||
Message: msg,
|
||||
}
|
||||
resp, err := FilterClient.Filter(ctx, req)
|
||||
if err != nil {
|
||||
log.Error("DM: main filter err: %v", err)
|
||||
u.lock.Lock()
|
||||
u.MsgLevel = 0
|
||||
u.MsgAI = 0
|
||||
u.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
u.lock.Lock()
|
||||
u.MsgLevel = int64(resp.Level)
|
||||
if resp.Ai == nil {
|
||||
log.Error("DM: main filter err: miss ai scores")
|
||||
u.MsgAI = 0
|
||||
u.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
if len(resp.Ai.Scores) == 0 {
|
||||
u.MsgAI = 0
|
||||
u.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
u.MsgAI = int64(resp.Ai.Scores[0] * 10)
|
||||
u.lock.Unlock()
|
||||
return nil
|
||||
}
|
162
app/service/live/live-dm/dao/getCheckInfo_test.go
Normal file
162
app/service/live/live-dm/dao/getCheckInfo_test.go
Normal file
@ -0,0 +1,162 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
fansMedalService "go-common/app/service/live/fans_medal/api/liverpc"
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
liveUserService "go-common/app/service/live/live_user/api/liverpc"
|
||||
roomService "go-common/app/service/live/room/api/liverpc"
|
||||
userextService "go-common/app/service/live/userext/api/liverpc"
|
||||
acctountService "go-common/app/service/main/account/api"
|
||||
filterService "go-common/app/service/main/filter/api/grpc/v1"
|
||||
spyService "go-common/app/service/main/spy/api"
|
||||
)
|
||||
|
||||
func init() {
|
||||
dir, _ := filepath.Abs("../cmd/test.toml")
|
||||
flag.Set("conf", dir)
|
||||
var err error
|
||||
if err = conf.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// InitAPI()
|
||||
// InitGrpc(conf.Conf)
|
||||
UserExtServiceClient = userextService.New(getConf("userext"))
|
||||
LiveUserServiceClient = liveUserService.New(getConf("liveUser"))
|
||||
FansMedalServiceClient = fansMedalService.New(getConf("fansMedal"))
|
||||
RoomServiceClient = roomService.New(getConf("room"))
|
||||
ac, err = acctountService.NewClient(conf.Conf.AccClient)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
vipCli, err = newVipService(conf.Conf.XuserClent)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
SpyClient, err = spyService.NewClient(conf.Conf.SpyClient)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
FilterClient, err = filterService.NewClient(conf.Conf.FilterClient)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestDMConf_Get
|
||||
func TestDMConf_Get(t *testing.T) {
|
||||
dc := &DMConf{}
|
||||
if err := dc.Get(context.TODO(), 111, 222, conf.Conf); err != nil {
|
||||
t.Error("获取弹幕配置失败", err)
|
||||
}
|
||||
if dc.Color == 0 && dc.Length == 0 && dc.Mode == 0 {
|
||||
t.Error("获取弹幕配置失败, 返回值错误")
|
||||
}
|
||||
fmt.Println("##### Mode: ", dc.Mode)
|
||||
fmt.Println("##### Color: ", dc.Color)
|
||||
fmt.Println("##### Length: ", dc.Length)
|
||||
}
|
||||
|
||||
//TODO 未测试
|
||||
//group=fat1 DEPLOY_ENV=uat go test -run TestUserInfo_Get
|
||||
func TestUserInfo_Get(t *testing.T) {
|
||||
u := &UserInfo{}
|
||||
if err := u.Get(context.TODO(), 110000232); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if u.UserLever == 0 && u.UserScore == 0 {
|
||||
t.Error("返回值错误")
|
||||
}
|
||||
fmt.Println("#### UserLever: ", u.UserLever)
|
||||
fmt.Println("#### UserScore: ", u.UserScore)
|
||||
fmt.Println("### Usercolor: ", u.ULevelColor)
|
||||
}
|
||||
|
||||
//DEPLOY_ENV=uat go test -run TestUserInfo_GetVipInfo
|
||||
func TestUserInfo_GetVipInfo(t *testing.T) {
|
||||
u := &UserInfo{}
|
||||
if err := u.GetVipInfo(context.TODO(), 2); err != nil {
|
||||
t.Error("获取老爷失败: ", err)
|
||||
}
|
||||
fmt.Println("#### VIP: ", u.Vip)
|
||||
fmt.Println("### SVIP: ", u.Svip)
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestUserInfo_GetPrivilegeType
|
||||
func TestUserInfo_GetPrivilegeType(t *testing.T) {
|
||||
u := &UserInfo{}
|
||||
if err := u.GetPrivilegeType(context.TODO(), 10799340, 6810576); err != nil {
|
||||
t.Error("返回值错误: ", err)
|
||||
}
|
||||
fmt.Println("PrivilegeType", u.PrivilegeType)
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestUserInfo_IsRoomAdmin
|
||||
func TestUserInfo_IsRoomAdmin(t *testing.T) {
|
||||
u := &UserInfo{}
|
||||
if err := u.IsRoomAdmin(context.TODO(), 1877309, 5392); err != nil {
|
||||
t.Error("返回值错误: ", err)
|
||||
}
|
||||
fmt.Println("IsRoomAdmin->", u.RoomAdmin)
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestUserInfo_GetFansMedal
|
||||
func TestUserInfo_GetFansMedal(t *testing.T) {
|
||||
m := &FansMedalInfo{}
|
||||
if err := m.GetFansMedal(context.TODO(), 83940); err != nil {
|
||||
t.Error("获取粉丝勋章失败: ", err)
|
||||
}
|
||||
fmt.Println("#####RUID: ", m.RUID)
|
||||
fmt.Println("#####MedalLevel: ", m.MedalLevel)
|
||||
fmt.Println("#####MedalName: ", m.MedalName)
|
||||
fmt.Println("#####MColor: ", m.MColor)
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestRoomConf_Get
|
||||
func TestRoomConf_Get(t *testing.T) {
|
||||
r := &RoomConf{}
|
||||
if err := r.Get(context.TODO(), 1016); err != nil {
|
||||
t.Error("获取房间配置失败: ", err)
|
||||
}
|
||||
fmt.Println("RoomID->", r.RoomID)
|
||||
fmt.Println("UID->", r.UID)
|
||||
fmt.Println("RoomShield->", r.RoomShield)
|
||||
fmt.Println("Anchor->", r.Anchor)
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestUserBindInfo_Get
|
||||
func TestUserBindInfo_Get(t *testing.T) {
|
||||
u := &UserBindInfo{}
|
||||
if err := u.Get(context.TODO(), 222); err != nil {
|
||||
t.Error("获取用户绑定信息失败: ", err)
|
||||
}
|
||||
fmt.Println("Identification->", u.Identification)
|
||||
fmt.Println("MobileVerify->", u.MobileVerify)
|
||||
fmt.Println("Uname->", u.Uname)
|
||||
fmt.Println("URank->", u.URank)
|
||||
}
|
||||
|
||||
//DEPLOY_ENV=uat go test -run TestGerUserScore
|
||||
func TestGerUserScore(t *testing.T) {
|
||||
u := &UserScore{}
|
||||
if err := u.GetUserScore(context.TODO(), 111); err != nil {
|
||||
t.Error("获取用户真实分失败:", err)
|
||||
}
|
||||
fmt.Println("###### UserScore:", u.UserScore)
|
||||
}
|
||||
|
||||
//缺少souce值
|
||||
//DEPLOY_ENV=uat go test -run TestGetMsgScore
|
||||
func TestGetMsgScore(t *testing.T) {
|
||||
u := &UserScore{}
|
||||
if err := u.GetMsgScore(context.TODO(), "fuck"); err != nil {
|
||||
t.Error("获取真实分失败:", err)
|
||||
}
|
||||
fmt.Println("MsgLeve->", u.MsgLevel)
|
||||
fmt.Println("MsgAI=>", u.MsgAI)
|
||||
}
|
234
app/service/live/live-dm/dao/getDMConf.go
Normal file
234
app/service/live/live-dm/dao/getDMConf.go
Normal file
@ -0,0 +1,234 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
activityService "go-common/app/service/live/activity/api/liverpc/v1"
|
||||
rankdbService "go-common/app/service/live/rankdb/api/liverpc/v1"
|
||||
rcService "go-common/app/service/live/rc/api/liverpc/v1"
|
||||
roomService "go-common/app/service/live/room/api/liverpc/v2"
|
||||
userextService "go-common/app/service/live/userext/api/liverpc/v1"
|
||||
acctountService "go-common/app/service/main/account/api"
|
||||
"go-common/library/log"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
//CommentTitle 头衔信息
|
||||
type CommentTitle struct {
|
||||
OldTitle string `json:"oldtitle"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
|
||||
//GetUnameColor 获取用户的昵称颜色
|
||||
func (u *UserInfo) GetUnameColor(ctx context.Context, uid int64, rid int64) error {
|
||||
req := &userextService.ColorGetUnameColorReq{
|
||||
Uid: uid,
|
||||
RoomId: rid,
|
||||
}
|
||||
resq, err := UserExtServiceClient.V1Color.GetUnameColor(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: UserExt GetUnameColor err: %v", err)
|
||||
}
|
||||
u.lock.Lock()
|
||||
u.UnameColor = ""
|
||||
u.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
if resq.Code != 0 {
|
||||
log.Error("DM: UserExt GetUnameColor errror code: %d", resq.Code)
|
||||
u.lock.Lock()
|
||||
u.UnameColor = ""
|
||||
u.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
u.lock.Lock()
|
||||
u.UnameColor = resq.Data.UnameColor
|
||||
u.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
//GetSpeicalMedal 获取特殊勋章
|
||||
func (f *FansMedalInfo) GetSpeicalMedal(ctx context.Context, uid int64, rid int64) error {
|
||||
//更新special
|
||||
req := &activityService.UnionFansGetSpecialMedalReq{
|
||||
Uid: uid,
|
||||
Ruid: rid,
|
||||
}
|
||||
resq, err := ActivityServiceClient.V1UnionFans.GetSpecialMedal(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: GetSpecialMedal err: %v", err)
|
||||
}
|
||||
f.lock.Lock()
|
||||
f.SpecialMedal = ""
|
||||
f.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
if resq.Code != 0 {
|
||||
log.Error("DM: GetSpecialMedal err code: %d", resq.Code)
|
||||
f.lock.Lock()
|
||||
f.SpecialMedal = ""
|
||||
f.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
f.lock.Lock()
|
||||
f.SpecialMedal = resq.Data.SpecialMedal
|
||||
f.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
//GetUserLevelRank 获取用户等级RANK
|
||||
func (u *UserInfo) GetUserLevelRank(ctx context.Context, uid int64) error {
|
||||
defer u.lock.Unlock()
|
||||
req := &rankdbService.UserRankGetUserRankReq{
|
||||
Uid: uid,
|
||||
Type: "user_level",
|
||||
}
|
||||
resq, err := RankdbServiceClient.V1UserRank.GetUserRank(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: GetUserRank err: %v", err)
|
||||
}
|
||||
u.lock.Lock()
|
||||
u.ULevelRank = 1000000
|
||||
return nil
|
||||
}
|
||||
if resq.Code != 0 {
|
||||
log.Error("DM: GetUserRank error code: %d", resq.Code)
|
||||
u.lock.Lock()
|
||||
u.ULevelRank = 1000000
|
||||
return nil
|
||||
}
|
||||
u.lock.Lock()
|
||||
u.ULevelRank = resq.Data.Rank
|
||||
return nil
|
||||
}
|
||||
|
||||
//GetCommentTitle 获取头衔
|
||||
func (c *CommentTitle) GetCommentTitle(ctx context.Context) error {
|
||||
req := &rcService.UserTitleGetCommentTitleReq{}
|
||||
resq, err := RcServiceClient.V1UserTitle.GetCommentTitle(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: GetCommentTitle err: %v", err)
|
||||
}
|
||||
c.OldTitle = ""
|
||||
c.Title = ""
|
||||
return nil
|
||||
}
|
||||
if resq.Code != 0 {
|
||||
log.Error("DM: GetCommentTitle error code: %d", resq.Code)
|
||||
c.OldTitle = ""
|
||||
c.Title = ""
|
||||
return nil
|
||||
}
|
||||
if len(resq.Data) == 0 {
|
||||
c.OldTitle = ""
|
||||
c.Title = ""
|
||||
return nil
|
||||
}
|
||||
|
||||
c.OldTitle = resq.Data[0]
|
||||
c.Title = resq.Data[1]
|
||||
return nil
|
||||
}
|
||||
|
||||
//GetMedalanchorName 获取勋章对应主播的昵称
|
||||
func (f *FansMedalInfo) GetMedalanchorName(ctx context.Context, uid int64) error {
|
||||
if uid == 0 {
|
||||
f.RUName = ""
|
||||
return nil
|
||||
}
|
||||
|
||||
req := &acctountService.MidReq{
|
||||
Mid: uid,
|
||||
}
|
||||
resp, err := ac.Profile3(ctx, req)
|
||||
if err != nil {
|
||||
log.Error("DM: acctountService Profile3 err: %v", err)
|
||||
f.lock.Lock()
|
||||
f.RUName = ""
|
||||
f.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
f.lock.Lock()
|
||||
f.RUName = resp.Profile.Name
|
||||
f.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
//GetMedalRoomid 获取勋章对应主播的房间
|
||||
func (f *FansMedalInfo) GetMedalRoomid(ctx context.Context, uid int64) error {
|
||||
if uid == 0 {
|
||||
f.lock.Lock()
|
||||
f.RoomID = 0
|
||||
f.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
req := &roomService.RoomRoomIdByUidReq{
|
||||
Uid: uid,
|
||||
}
|
||||
resp, err := RoomServiceClient.V2Room.RoomIdByUid(ctx, req)
|
||||
if err != nil {
|
||||
log.Error("DM: room RoomIdByUid err: %v", err)
|
||||
f.lock.Lock()
|
||||
f.RoomID = 0
|
||||
f.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
if resp.Code == 404 {
|
||||
f.lock.Lock()
|
||||
f.RoomID = 0
|
||||
f.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
if resp.Code != 0 {
|
||||
log.Error("DM: room RoomIdByUid err code: %d", resp.Code)
|
||||
f.lock.Lock()
|
||||
f.RoomID = 0
|
||||
f.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
f.lock.Lock()
|
||||
f.RoomID = resp.Data.RoomId
|
||||
f.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
//GetUserBubble 判断用户是否有气泡
|
||||
func (u *UserInfo) GetUserBubble(ctx context.Context, uid int64, roomid int64, bubble int64, guardLevel int) error {
|
||||
req := &userextService.BubbleGetBubbleReq{
|
||||
Uid: uid,
|
||||
RoomId: roomid,
|
||||
BubbleId: bubble,
|
||||
GuardLevel: int64(guardLevel),
|
||||
}
|
||||
defer u.lock.Unlock()
|
||||
resp, err := UserExtServiceClient.V1Bubble.GetBubble(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: userext Bubble check err: %v", err)
|
||||
}
|
||||
u.lock.Lock()
|
||||
u.Bubble = bubble
|
||||
return nil
|
||||
}
|
||||
if resp.Code != 0 {
|
||||
log.Error("DM: userext Bubble check err code: %d", resp.Code)
|
||||
u.lock.Lock()
|
||||
u.Bubble = bubble
|
||||
return nil
|
||||
}
|
||||
if resp.Data == nil {
|
||||
log.Error("DM: userext Bubble check err not data")
|
||||
u.lock.Lock()
|
||||
u.Bubble = bubble
|
||||
return nil
|
||||
}
|
||||
u.lock.Lock()
|
||||
u.Bubble = resp.Data.Bubble
|
||||
return nil
|
||||
}
|
153
app/service/live/live-dm/dao/getDMConf_test.go
Normal file
153
app/service/live/live-dm/dao/getDMConf_test.go
Normal file
@ -0,0 +1,153 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
activityService "go-common/app/service/live/activity/api/liverpc"
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
rankdbService "go-common/app/service/live/rankdb/api/liverpc"
|
||||
rcService "go-common/app/service/live/rc/api/liverpc"
|
||||
userextService "go-common/app/service/live/userext/api/liverpc"
|
||||
acctountService "go-common/app/service/main/account/api"
|
||||
"go-common/library/net/metadata"
|
||||
)
|
||||
|
||||
func init() {
|
||||
dir, _ := filepath.Abs("../cmd/test.toml")
|
||||
flag.Set("conf", dir)
|
||||
var err error
|
||||
if err = conf.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
UserExtServiceClient = userextService.New(getConf("userext"))
|
||||
ActivityServiceClient = activityService.New(getConf("activity"))
|
||||
RankdbServiceClient = rankdbService.New(getConf("rankdbService"))
|
||||
RcServiceClient = rcService.New(getConf("rc"))
|
||||
|
||||
ac, err = acctountService.NewClient(conf.Conf.AccClient)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestUserInfo_GetUnameColor
|
||||
func TestUserInfo_GetUnameColor(t *testing.T) {
|
||||
u := &UserInfo{}
|
||||
if err := u.GetUnameColor(context.TODO(), 28272030, 10004); err != nil {
|
||||
t.Error("获取用户昵称颜色失败: ", err)
|
||||
}
|
||||
fmt.Println("UnameColor->", u.UnameColor)
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestUserInfo_GetSpeicalMedal
|
||||
func TestUserInfo_GetSpeicalMedal(t *testing.T) {
|
||||
m := &FansMedalInfo{}
|
||||
if err := m.GetSpeicalMedal(context.TODO(), 111, 222); err != nil {
|
||||
t.Error("获取特殊勋章信息失败:", err)
|
||||
}
|
||||
fmt.Println("SpecialMedal->", m.SpecialMedal)
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestUserInfo_GetUserLevelRank
|
||||
func TestUserInfo_GetUserLevelRank(t *testing.T) {
|
||||
u := &UserInfo{}
|
||||
if err := u.GetUserLevelRank(context.TODO(), 111); err != nil {
|
||||
t.Error("获取用户等级RANK失败:", err)
|
||||
}
|
||||
fmt.Println("ULevelRank->", u.ULevelRank)
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestCommentTitle_GetCommentTitle
|
||||
func TestCommentTitle_GetCommentTitle(t *testing.T) {
|
||||
c := &CommentTitle{}
|
||||
|
||||
ctx1 := metadata.NewContext(context.TODO(), metadata.MD{})
|
||||
if md, ok := metadata.FromContext(ctx1); ok {
|
||||
md[metadata.Mid] = 5200
|
||||
}
|
||||
if err := c.GetCommentTitle(ctx1); err != nil {
|
||||
t.Error("获取用户头衔失败:", err)
|
||||
}
|
||||
fmt.Println("OldTitle->", c.OldTitle)
|
||||
fmt.Println("Title->", c.Title)
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestFansMedalInfo_GetMedalanchorName
|
||||
func TestFansMedalInfo_GetMedalanchorName(t *testing.T) {
|
||||
f := &FansMedalInfo{}
|
||||
if err := f.GetMedalanchorName(context.TODO(), 222); err != nil {
|
||||
t.Error("获取勋章对应主播昵称错误:", err)
|
||||
}
|
||||
fmt.Println("RUName->", f.RUName)
|
||||
}
|
||||
|
||||
//group=fat1 DEPLOY_ENV=uat go test -run TestUserInof_GetUserBubble
|
||||
func TestUserInof_GetUserBubble(t *testing.T) {
|
||||
u := &UserInfo{}
|
||||
if err := u.GetUserBubble(context.TODO(), 1, 1, 1, 1); err != nil {
|
||||
t.Error("GetUserBubble调用失败")
|
||||
}
|
||||
if u.Bubble != 1 {
|
||||
t.Error("判断气泡失败 uid 1 roomid 1 bubble 1: bubble: ", u.Bubble)
|
||||
}
|
||||
fmt.Println("Bubble1->", u.Bubble)
|
||||
if err := u.GetUserBubble(context.TODO(), 1, 2, 1, 1); err != nil {
|
||||
t.Error("GetUserBubble调用失败")
|
||||
}
|
||||
if u.Bubble != 0 {
|
||||
t.Error("判断气泡失败 uid 1 roomid 2 bubble 1: bubble: ", u.Bubble)
|
||||
}
|
||||
fmt.Println("Bubble2->", u.Bubble)
|
||||
|
||||
}
|
||||
|
||||
// //group=qa01 DEPLOY_ENV=uat go test -run TestUserInfo_GetUserLevelColor
|
||||
// func TestUserInfo_GetUserLevelColor(t *testing.T) {
|
||||
// u := &UserInfo{}
|
||||
// if err := u.GetUserLevelColor(52); err != nil {
|
||||
// t.Error("返回值错误: ", err)
|
||||
// }
|
||||
|
||||
// if u.ULevelColor != 16752445 {
|
||||
// t.Error("51级以上颜色错误 16752445 ->", u.ULevelColor)
|
||||
// }
|
||||
|
||||
// if err := u.GetUserLevelColor(42); err != nil {
|
||||
// t.Error("返回值错误: ", err)
|
||||
// }
|
||||
// if u.ULevelColor != 16746162 {
|
||||
// t.Error("51-41级颜色错误 16752445 ->", u.ULevelColor)
|
||||
// }
|
||||
|
||||
// if err := u.GetUserLevelColor(32); err != nil {
|
||||
// t.Error("返回值错误: ", err)
|
||||
// }
|
||||
// if u.ULevelColor != 10512625 {
|
||||
// t.Error("41-31级颜色错误 10512625 ->", u.ULevelColor)
|
||||
// }
|
||||
|
||||
// if err := u.GetUserLevelColor(22); err != nil {
|
||||
// t.Error("返回值错误: ", err)
|
||||
// }
|
||||
// if u.ULevelColor != 5805790 {
|
||||
// t.Error("31-21级颜色错误 16752445 ->", u.ULevelColor)
|
||||
// }
|
||||
|
||||
// if err := u.GetUserLevelColor(12); err != nil {
|
||||
// t.Error("返回值错误: ", err)
|
||||
// }
|
||||
// if u.ULevelColor != 6406234 {
|
||||
// t.Error("21-11级颜色错误 16752445 ->", u.ULevelColor)
|
||||
// }
|
||||
|
||||
// if err := u.GetUserLevelColor(2); err != nil {
|
||||
// t.Error("返回值错误: ", err)
|
||||
// }
|
||||
// if u.ULevelColor != 9868950 {
|
||||
// t.Error("0-11级颜色错误 16752445 ->", u.ULevelColor)
|
||||
// }
|
||||
// }
|
51
app/service/live/live-dm/dao/gethistory.go
Normal file
51
app/service/live/live-dm/dao/gethistory.go
Normal file
@ -0,0 +1,51 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"go-common/library/cache/redis"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
//GetHistoryData 获取历史数据
|
||||
func (d *Dao) GetHistoryData(ctx context.Context, roomid int64) (result map[string][]string, err error) {
|
||||
var conn = d.redis.Get(ctx)
|
||||
defer conn.Close()
|
||||
var admkey = fmt.Sprintf("%s%d", _adminMsgHistoryCache, roomid)
|
||||
var userkey = fmt.Sprintf("%s%d", _msgHistoryCache, roomid)
|
||||
|
||||
if err = conn.Send("LRANGE", admkey, 0, 9); err != nil {
|
||||
log.Error("DM: LRANGE ADMIN KEY ROOMID %d ERR:%v", roomid, err)
|
||||
}
|
||||
if err = conn.Send("LRANGE", userkey, 0, 9); err != nil {
|
||||
log.Error("DM: LRANGE USER KEY ROOMID %d ERR:%v", roomid, err)
|
||||
}
|
||||
|
||||
if err = conn.Flush(); err != nil {
|
||||
log.Error("DM: Flush KEY ROOMID %d ERR:%v", roomid, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var admin, user [][]byte
|
||||
admin, err = redis.ByteSlices(conn.Receive())
|
||||
if err != nil {
|
||||
log.Error("DM: ByteSlices ADMIN KEY ROOMID %d ERR:%v", roomid, err)
|
||||
return nil, err
|
||||
}
|
||||
user, err = redis.ByteSlices(conn.Receive())
|
||||
if err != nil {
|
||||
log.Error("DM: ByteSlices USER KEY ROOMID %d ERR:%v", roomid, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result = make(map[string][]string)
|
||||
result["admin"] = make([]string, 0, 10)
|
||||
result["room"] = make([]string, 0, 10)
|
||||
for i := len(admin) - 1; i >= 0; i-- {
|
||||
result["admin"] = append(result["admin"], string(admin[i]))
|
||||
}
|
||||
for i := len(user) - 1; i >= 0; i-- {
|
||||
result["room"] = append(result["room"], string(user[i]))
|
||||
}
|
||||
return result, nil
|
||||
}
|
93
app/service/live/live-dm/dao/grpc.go
Normal file
93
app/service/live/live-dm/dao/grpc.go
Normal file
@ -0,0 +1,93 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
broadcasrtService "go-common/app/service/live/broadcast-proxy/api/v1"
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
xuserService "go-common/app/service/live/xuser/api/grpc/v1"
|
||||
acctountService "go-common/app/service/main/account/api"
|
||||
filterService "go-common/app/service/main/filter/api/grpc/v1"
|
||||
locationService "go-common/app/service/main/location/api"
|
||||
spyService "go-common/app/service/main/spy/api"
|
||||
"go-common/library/net/rpc/warden"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
//LocationAppID location服务注册ID
|
||||
const locationAppID = "location.service"
|
||||
const vipAppID = "live.xuser"
|
||||
|
||||
var (
|
||||
ac acctountService.AccountClient
|
||||
vipCli xuserService.VipClient
|
||||
//FilterClient 屏蔽词过滤
|
||||
FilterClient filterService.FilterClient
|
||||
//LcClient 地理区域信息
|
||||
LcClient locationService.LocationClient
|
||||
//SpyClient 用户真实分
|
||||
SpyClient spyService.SpyClient
|
||||
//BcastClient 弹幕推送
|
||||
BcastClient *broadcasrtService.Client
|
||||
//UserExp 用户等级
|
||||
userExp *xuserService.Client
|
||||
//isAdmin 房管
|
||||
isAdmin xuserService.RoomAdminClient
|
||||
)
|
||||
|
||||
//InitGrpc 初始化grpcclient
|
||||
func InitGrpc(c *conf.Config) {
|
||||
var err error
|
||||
ac, err = acctountService.NewClient(c.AccClient)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
FilterClient, err = filterService.NewClient(c.FilterClient)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
LcClient, err = newLocationClient(c.LocationClient)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
vipCli, err = newVipService(c.XuserClent)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
SpyClient, err = spyService.NewClient(c.SpyClient)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
BcastClient, err = broadcasrtService.NewClient(c.BcastClient)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
userExp, err = xuserService.NewClient(c.UExpClient)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
isAdmin, err = xuserService.NewXuserRoomAdminClient(c.IsAdminClient)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
//创建Location服务client
|
||||
func newLocationClient(cfg *warden.ClientConfig, opts ...grpc.DialOption) (locationService.LocationClient, error) {
|
||||
client := warden.NewClient(cfg, opts...)
|
||||
conn, err := client.Dial(context.Background(), "discovery://default/"+locationAppID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return locationService.NewLocationClient(conn), nil
|
||||
}
|
||||
|
||||
func newVipService(cfg *warden.ClientConfig, opts ...grpc.DialOption) (xuserService.VipClient, error) {
|
||||
client := warden.NewClient(cfg, opts...)
|
||||
conn, err := client.Dial(context.Background(), "discovery://default/"+vipAppID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return xuserService.NewVipClient(conn), nil
|
||||
}
|
30
app/service/live/live-dm/dao/ipdb.go
Normal file
30
app/service/live/live-dm/dao/ipdb.go
Normal file
@ -0,0 +1,30 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"github.com/ipipdotnet/ipdb-go"
|
||||
)
|
||||
|
||||
const (
|
||||
ip4dbaddr = "/data/conf/v4.ipdb"
|
||||
ip6dbaddr = "/data/conf/v6.ipdb"
|
||||
)
|
||||
|
||||
var (
|
||||
//IP4db ip4地址库
|
||||
IP4db *ipdb.City
|
||||
//IP6db ip6地址库
|
||||
IP6db *ipdb.City
|
||||
)
|
||||
|
||||
//InitIPdb 初始化IPdb
|
||||
func InitIPdb() {
|
||||
var err error
|
||||
IP4db, err = ipdb.NewCity(ip4dbaddr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
IP6db, err = ipdb.NewCity(ip6dbaddr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
65
app/service/live/live-dm/dao/liveRPC.go
Normal file
65
app/service/live/live-dm/dao/liveRPC.go
Normal file
@ -0,0 +1,65 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
activityService "go-common/app/service/live/activity/api/liverpc"
|
||||
avService "go-common/app/service/live/av/api/liverpc"
|
||||
bannedService "go-common/app/service/live/banned_service/api/liverpc"
|
||||
fansMedalService "go-common/app/service/live/fans_medal/api/liverpc"
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
liveUserService "go-common/app/service/live/live_user/api/liverpc"
|
||||
rankdbService "go-common/app/service/live/rankdb/api/liverpc"
|
||||
rcService "go-common/app/service/live/rc/api/liverpc"
|
||||
roomService "go-common/app/service/live/room/api/liverpc"
|
||||
liveBroadCast "go-common/app/service/live/third_api/liveBroadcast"
|
||||
userService "go-common/app/service/live/user/api/liverpc"
|
||||
userextService "go-common/app/service/live/userext/api/liverpc"
|
||||
"go-common/library/net/rpc/liverpc"
|
||||
)
|
||||
|
||||
var (
|
||||
// BannedServiceClient liveRpc banner_service api
|
||||
BannedServiceClient *bannedService.Client
|
||||
// RoomServiceClient liveRpc room service api
|
||||
RoomServiceClient *roomService.Client
|
||||
// LiveUserServiceClient liveRpc liveUser service api
|
||||
LiveUserServiceClient *liveUserService.Client
|
||||
// AvServiceClient liveRpc av service api
|
||||
AvServiceClient *avService.Client
|
||||
//FansMedalServiceClient liverpc fansmedal service api
|
||||
FansMedalServiceClient *fansMedalService.Client
|
||||
//ActivityServiceClient liverpc activity service api
|
||||
ActivityServiceClient *activityService.Client
|
||||
//RcServiceClient liverpc rc service api
|
||||
RcServiceClient *rcService.Client
|
||||
//RankdbServiceClient liverpc rankdb service api
|
||||
RankdbServiceClient *rankdbService.Client
|
||||
//UserExtServiceClient liverpc userext service api
|
||||
UserExtServiceClient *userextService.Client
|
||||
//LiveBroadCastClient liverpc thirdApi
|
||||
LiveBroadCastClient *liveBroadCast.Client
|
||||
//UserClient liveRpc user api
|
||||
userClient *userService.Client
|
||||
)
|
||||
|
||||
//InitAPI init all service APIS
|
||||
func InitAPI() {
|
||||
BannedServiceClient = bannedService.New(getConf("banneDService"))
|
||||
RoomServiceClient = roomService.New(getConf("room"))
|
||||
LiveUserServiceClient = liveUserService.New(getConf("liveUser"))
|
||||
AvServiceClient = avService.New(getConf("avService"))
|
||||
FansMedalServiceClient = fansMedalService.New(getConf("fansMedal"))
|
||||
ActivityServiceClient = activityService.New(getConf("activity"))
|
||||
RcServiceClient = rcService.New(getConf("rc"))
|
||||
RankdbServiceClient = rankdbService.New(getConf("rankdbService"))
|
||||
UserExtServiceClient = userextService.New(getConf("userext"))
|
||||
LiveBroadCastClient = liveBroadCast.New(conf.Conf.HTTPClient)
|
||||
userClient = userService.New(getConf("user"))
|
||||
}
|
||||
|
||||
func getConf(appName string) *liverpc.ClientConfig {
|
||||
c := conf.Conf.LiveRPC
|
||||
if c != nil {
|
||||
return c[appName]
|
||||
}
|
||||
return nil
|
||||
}
|
111
app/service/live/live-dm/dao/ratelimit.go
Normal file
111
app/service/live/live-dm/dao/ratelimit.go
Normal file
@ -0,0 +1,111 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"go-common/library/cache/redis"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// LimitCheckInfo 频率限制检查参数
|
||||
type LimitCheckInfo struct {
|
||||
UID int64
|
||||
RoomID int64
|
||||
Msg string
|
||||
MsgType int64
|
||||
Dao *Dao
|
||||
Conf *LimitConf
|
||||
}
|
||||
|
||||
const (
|
||||
_MaxGiftMsgNum = "r:m:stormmsgcount:"
|
||||
_MAXMsgNum = "r:m:rmx:"
|
||||
)
|
||||
|
||||
// LimitPerSec 每秒发言限制
|
||||
func (l *LimitCheckInfo) LimitPerSec(ctx context.Context) error {
|
||||
key := fmt.Sprintf("%d.%d", l.UID, time.Now().Unix())
|
||||
var conn = l.Dao.redis.Get(ctx)
|
||||
defer conn.Close()
|
||||
ret, err := conn.Do("SET", key, 1, "EX", 1, "NX")
|
||||
if err != nil {
|
||||
log.Error("limitPerSec:conn.Do(SET EX NX) %s %d %v", key, 1, err)
|
||||
return nil
|
||||
}
|
||||
if ret != nil {
|
||||
return nil
|
||||
}
|
||||
return ecode.Error(0, "msg in 1s")
|
||||
}
|
||||
|
||||
//LimitSameMsg 同一个用户同一房间5s 只能发送一条相同弹幕
|
||||
func (l *LimitCheckInfo) LimitSameMsg(ctx context.Context) error {
|
||||
key := fmt.Sprintf("%d.%s", l.RoomID, md5.Sum([]byte(strconv.FormatInt(l.UID, 10)+l.Msg)))
|
||||
var conn = l.Dao.redis.Get(ctx)
|
||||
defer conn.Close()
|
||||
ret, err := conn.Do("SET", key, 1, "EX", 5, "NX")
|
||||
if err != nil {
|
||||
log.Error("DM LimitSameMsg conn.Do(SET, %s, 1, EX, 5, NX) error(%v)", key, err)
|
||||
return nil
|
||||
}
|
||||
if ret != nil {
|
||||
return nil
|
||||
}
|
||||
return ecode.Error(0, "msg repeat")
|
||||
}
|
||||
|
||||
//LimitRoomPerSecond 单房间每秒只能发送制定条数弹幕
|
||||
func (l *LimitCheckInfo) LimitRoomPerSecond(ctx context.Context) error {
|
||||
maxNum := l.Conf.DmNum
|
||||
percent := l.Conf.DMPercent
|
||||
danNum := maxNum * percent / 100.0
|
||||
giftNum := maxNum - danNum
|
||||
|
||||
msgKey := fmt.Sprintf("%s.%d.%d", _MAXMsgNum, l.RoomID, time.Now().Unix())
|
||||
giftKey := fmt.Sprintf("%s.%d.%d", _MaxGiftMsgNum, l.RoomID, time.Now().Unix())
|
||||
var conn = l.Dao.redis.Get(ctx)
|
||||
defer conn.Close()
|
||||
|
||||
if l.MsgType != 0 {
|
||||
//礼物弹幕
|
||||
if count, err := redis.Int64(conn.Do("INCRBY", giftKey, 1)); err != nil {
|
||||
log.Error("DMRateLimit: LimitRoomPerSecond INCRBY err: %v", err)
|
||||
} else {
|
||||
if count > giftNum {
|
||||
return ecode.Error(0, "max limit")
|
||||
}
|
||||
}
|
||||
if _, err := conn.Do("EXPIRE", giftKey, 2); err != nil {
|
||||
log.Error("DMRateLimit: LimitRoomPerSecond EXPIRE err: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
//普通弹幕
|
||||
var max = maxNum
|
||||
if exit, err := redis.Bool(conn.Do("EXISTS", giftKey)); err != nil {
|
||||
log.Error("DMRateLimit: LimitRoomPerSecond EXISTS gift err: %v", err)
|
||||
} else {
|
||||
if exit {
|
||||
max = danNum
|
||||
} else {
|
||||
max = maxNum
|
||||
}
|
||||
}
|
||||
|
||||
if count, err := redis.Int64(conn.Do("INCRBY", msgKey, 1)); err != nil {
|
||||
log.Error("DMRateLimit: LimitRoomPerSecond INCR err: %v", err)
|
||||
} else {
|
||||
if count > max {
|
||||
return ecode.Error(0, "max limit")
|
||||
}
|
||||
}
|
||||
if _, err := conn.Do("EXPIRE", msgKey, 2); err != nil {
|
||||
log.Error("DMRateLimit: LimitRoomPerSecond EXPIRE err: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
74
app/service/live/live-dm/dao/ratelimit_test.go
Normal file
74
app/service/live/live-dm/dao/ratelimit_test.go
Normal file
@ -0,0 +1,74 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func init() {
|
||||
dir, _ := filepath.Abs("../cmd/test.toml")
|
||||
flag.Set("conf", dir)
|
||||
var err error
|
||||
if err = conf.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
InitAPI()
|
||||
InitGrpc(conf.Conf)
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestLimitPerSec
|
||||
func TestLimitPerSec(t *testing.T) {
|
||||
l := LimitCheckInfo{
|
||||
UID: 111,
|
||||
RoomID: 222,
|
||||
Msg: "6666",
|
||||
Dao: New(conf.Conf),
|
||||
MsgType: 0,
|
||||
Conf: &LimitConf{
|
||||
DmNum: 20,
|
||||
DMPercent: 25,
|
||||
},
|
||||
}
|
||||
if err := l.LimitPerSec(context.TODO()); err != nil {
|
||||
t.Error("每秒限制错误:", err)
|
||||
}
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestLimitSameMsg
|
||||
func TestLimitSameMsg(t *testing.T) {
|
||||
l := LimitCheckInfo{
|
||||
UID: 111,
|
||||
RoomID: 222,
|
||||
Msg: "6666",
|
||||
Dao: New(conf.Conf),
|
||||
MsgType: 0,
|
||||
Conf: &LimitConf{
|
||||
DmNum: 20,
|
||||
DMPercent: 25,
|
||||
},
|
||||
}
|
||||
if err := l.LimitSameMsg(context.TODO()); err != nil {
|
||||
t.Error("5秒相同发言错误:", err)
|
||||
}
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestLimitRoomPerSecond
|
||||
func TestLimitRoomPerSecond(t *testing.T) {
|
||||
l := LimitCheckInfo{
|
||||
UID: 111,
|
||||
RoomID: 222,
|
||||
Msg: "6666",
|
||||
Dao: New(conf.Conf),
|
||||
MsgType: 0,
|
||||
Conf: &LimitConf{
|
||||
DmNum: 20,
|
||||
DMPercent: 25,
|
||||
},
|
||||
}
|
||||
if err := l.LimitRoomPerSecond(context.TODO()); err != nil {
|
||||
t.Error("每秒20弹幕错误:", err)
|
||||
}
|
||||
}
|
144
app/service/live/live-dm/dao/send.go
Normal file
144
app/service/live/live-dm/dao/send.go
Normal file
@ -0,0 +1,144 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
broadcasrtService "go-common/app/service/live/broadcast-proxy/api/v1"
|
||||
"go-common/app/service/live/live-dm/model"
|
||||
roomService "go-common/app/service/live/room/api/liverpc/v1"
|
||||
"go-common/library/cache/redis"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
const (
|
||||
_adminMsgHistoryCache = "cache:last10_roomadminmsg:"
|
||||
_msgHistoryCache = "cache:last10_roommsg:"
|
||||
)
|
||||
|
||||
//SaveHistory 弹幕历史存入redis
|
||||
func (d *Dao) SaveHistory(ctx context.Context, hm string, adm bool, rid int64) {
|
||||
var conn = d.redis.Get(ctx)
|
||||
defer conn.Close()
|
||||
if adm {
|
||||
admKey := fmt.Sprintf("%s%d", _adminMsgHistoryCache, rid)
|
||||
if err := conn.Send("LPUSH", admKey, hm); err != nil {
|
||||
log.Error("DM: SaveHistory LPUSH err: %v", err)
|
||||
}
|
||||
if err := conn.Send("LLEN", admKey); err != nil {
|
||||
log.Error("DM: SaveHistory LLEN err: %v", err)
|
||||
return
|
||||
}
|
||||
if err := conn.Flush(); err != nil {
|
||||
log.Error("DM: SaveHistory Flush err: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := conn.Receive(); err != nil {
|
||||
log.Error("DM: SaveHistory LPUSH err: %v", err)
|
||||
}
|
||||
count, err := redis.Int64(conn.Receive())
|
||||
if err != nil {
|
||||
log.Error("DM: SaveHistory LPUSH LLEN err: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if count > 15 {
|
||||
err := conn.Send("LTRIM", admKey, 0, 9)
|
||||
if err != nil {
|
||||
log.Error("DM: SaveHistory LTRIM err: %v", err)
|
||||
}
|
||||
}
|
||||
if err := conn.Send("EXPIRE", admKey, 86400); err != nil {
|
||||
log.Error("DM: SaveHistory EXPIRE err: %v", err)
|
||||
}
|
||||
if err := conn.Flush(); err != nil {
|
||||
log.Error("DM: SaveHistory Flush err: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
userKey := fmt.Sprintf("%s%d", _msgHistoryCache, rid)
|
||||
if err := conn.Send("LPUSH", userKey, hm); err != nil {
|
||||
log.Error("DM: SaveHistory LPUSH err: %v", err)
|
||||
}
|
||||
if err := conn.Send("LLEN", userKey); err != nil {
|
||||
log.Error("DM: SaveHistory LLEN err: %v", err)
|
||||
return
|
||||
}
|
||||
if err := conn.Flush(); err != nil {
|
||||
log.Error("DM: SaveHistory Flush err: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := conn.Receive(); err != nil {
|
||||
log.Error("DM: SaveHistory Receive LPUSH err: %v", err)
|
||||
}
|
||||
count, err := redis.Int64(conn.Receive())
|
||||
if err != nil {
|
||||
log.Error("DM: SaveHistory Int64 err: %v", err)
|
||||
return
|
||||
}
|
||||
if count > 15 {
|
||||
if err := conn.Send("LTRIM", userKey, 0, 9); err != nil {
|
||||
log.Error("DM: SaveHistory LTRIM err: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := conn.Send("EXPIRE", userKey, 86400); err != nil {
|
||||
log.Error("DM: SaveHistory EXPIRE err: %v", err)
|
||||
}
|
||||
|
||||
if err := conn.Flush(); err != nil {
|
||||
log.Error("DM: SaveHistory Flush err: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
//IncrDMNum 弹幕条数
|
||||
func IncrDMNum(ctx context.Context, rid int64, mode int64) {
|
||||
req := &roomService.RoomIncrDanmuSendNumReq{
|
||||
RoomId: rid,
|
||||
Mode: mode,
|
||||
}
|
||||
resp, err := RoomServiceClient.V1Room.IncrDanmuSendNum(ctx, req)
|
||||
if err != nil {
|
||||
log.Error("DM: IncrDMNum err: %v", err)
|
||||
return
|
||||
}
|
||||
if resp.Code != 0 {
|
||||
log.Error("DM: IncrDMNum err code: %d", resp.Code)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
//SendBroadCast 发送弹幕(http)
|
||||
func SendBroadCast(ctx context.Context, sm string, rid int64) error {
|
||||
err := LiveBroadCastClient.PushBroadcast(ctx, rid, 0, sm)
|
||||
if err != nil {
|
||||
log.Error("DM: SendBroadCast err: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//SendBroadCastGrpc 调用GRPC发送弹幕
|
||||
func SendBroadCastGrpc(ctx context.Context, sm string, rid int64) error {
|
||||
req := &broadcasrtService.RoomMessageRequest{
|
||||
RoomId: int32(rid),
|
||||
Message: sm,
|
||||
}
|
||||
_, err := BcastClient.DanmakuClient.RoomMessage(ctx, req)
|
||||
if err != nil {
|
||||
log.Error("DM: SendBroadCastGrpc err: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//SendBNDatabus 拜年祭制定房间投递到databus
|
||||
func SendBNDatabus(ctx context.Context, uid int64, info *model.BNDatabus) {
|
||||
uids := strconv.FormatInt(uid, 10)
|
||||
if err := bndatabus.Send(ctx, uids, info); err != nil {
|
||||
log.Error("[service.live-dm.v1.bndatabus] send error(%v), record(%v)", err, info)
|
||||
}
|
||||
}
|
25
app/service/live/live-dm/dao/send_test.go
Normal file
25
app/service/live/live-dm/dao/send_test.go
Normal file
@ -0,0 +1,25 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func init() {
|
||||
dir, _ := filepath.Abs("../cmd/test.toml")
|
||||
flag.Set("conf", dir)
|
||||
var err error
|
||||
if err = conf.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
InitAPI()
|
||||
InitGrpc(conf.Conf)
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestIncrDMNum
|
||||
func TestIncrDMNum(t *testing.T) {
|
||||
IncrDMNum(context.TODO(), 5392, 2)
|
||||
}
|
22
app/service/live/live-dm/dao/white_list.go
Normal file
22
app/service/live/live-dm/dao/white_list.go
Normal file
@ -0,0 +1,22 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/library/cache/redis"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
//IsWhietListUID 通过UID判读是否是白名单用户
|
||||
func (d *Dao) IsWhietListUID(ctx context.Context, key string) (isWhite bool) {
|
||||
conn := d.whitelistredis.Get(ctx)
|
||||
defer conn.Close()
|
||||
|
||||
var err error
|
||||
isWhite, err = redis.Bool(conn.Do("EXISTS", key))
|
||||
if err != nil {
|
||||
log.Error("[DM] GetWhietListByUID redis err:%+v", err)
|
||||
return true
|
||||
}
|
||||
return
|
||||
}
|
29
app/service/live/live-dm/dao/white_list_test.go
Normal file
29
app/service/live/live-dm/dao/white_list_test.go
Normal file
@ -0,0 +1,29 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func init() {
|
||||
dir, _ := filepath.Abs("../cmd/test.toml")
|
||||
flag.Set("conf", dir)
|
||||
var err error
|
||||
if err = conf.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// DEPLOY_ENV=uat go test -run TestIsWhietListUID
|
||||
func TestIsWhietListUID(t *testing.T) {
|
||||
dao := New(conf.Conf)
|
||||
if isWhite := dao.IsWhietListUID(context.TODO(), "1111"); isWhite {
|
||||
t.Error("白名单判断失败")
|
||||
}
|
||||
if isWhite := dao.IsWhietListUID(context.TODO(), "13269933"); !isWhite {
|
||||
t.Error("白名单判断失败")
|
||||
}
|
||||
}
|
28
app/service/live/live-dm/model/BUILD
Normal file
28
app/service/live/live-dm/model/BUILD
Normal file
@ -0,0 +1,28 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["model.go"],
|
||||
importpath = "go-common/app/service/live/live-dm/model",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
14
app/service/live/live-dm/model/model.go
Normal file
14
app/service/live/live-dm/model/model.go
Normal file
@ -0,0 +1,14 @@
|
||||
package model
|
||||
|
||||
//BNDatabus 拜年祭投递消息
|
||||
type BNDatabus struct {
|
||||
Roomid int64 `json:"room_id"`
|
||||
UID int64 `json:"uid"`
|
||||
Uname string `json:"uname"`
|
||||
UserLever int64 `json:"user_level"`
|
||||
Color int64 `json:"color"`
|
||||
Msg string `json:"content"`
|
||||
Time int64 `json:"time"`
|
||||
MsgID string `json:"msg_id"`
|
||||
MsgType int64 `json:"msg_type"`
|
||||
}
|
35
app/service/live/live-dm/server/grpc/BUILD
Normal file
35
app/service/live/live-dm/server/grpc/BUILD
Normal file
@ -0,0 +1,35 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["server.go"],
|
||||
importpath = "go-common/app/service/live/live-dm/server/grpc",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/service/live/live-dm/api/grpc/v1:go_default_library",
|
||||
"//app/service/live/live-dm/conf:go_default_library",
|
||||
"//app/service/live/live-dm/dao:go_default_library",
|
||||
"//app/service/live/live-dm/service/v1:go_default_library",
|
||||
"//library/net/rpc/warden:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
25
app/service/live/live-dm/server/grpc/server.go
Normal file
25
app/service/live/live-dm/server/grpc/server.go
Normal file
@ -0,0 +1,25 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
dmg "go-common/app/service/live/live-dm/api/grpc/v1"
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
"go-common/app/service/live/live-dm/dao"
|
||||
dms "go-common/app/service/live/live-dm/service/v1"
|
||||
"go-common/library/net/rpc/warden"
|
||||
)
|
||||
|
||||
//Init 弹幕grpc 初始化
|
||||
func Init(c *conf.Config) {
|
||||
dao.InitAPI()
|
||||
dao.InitGrpc(c)
|
||||
dao.InitIPdb()
|
||||
dao.InitDatabus(c)
|
||||
dao.InitLancer(c)
|
||||
dao.InitTitan()
|
||||
s := warden.NewServer(nil)
|
||||
dmg.RegisterDMServer(s.Server(), dms.NewDMService(c))
|
||||
_, err := s.Start()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
35
app/service/live/live-dm/server/http/BUILD
Normal file
35
app/service/live/live-dm/server/http/BUILD
Normal file
@ -0,0 +1,35 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["http.go"],
|
||||
importpath = "go-common/app/service/live/live-dm/server/http",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/service/live/live-dm/conf:go_default_library",
|
||||
"//app/service/live/live-dm/service:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
"//library/net/http/blademaster:go_default_library",
|
||||
"//library/net/http/blademaster/middleware/verify:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
53
app/service/live/live-dm/server/http/http.go
Normal file
53
app/service/live/live-dm/server/http/http.go
Normal file
@ -0,0 +1,53 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
"go-common/app/service/live/live-dm/service"
|
||||
"go-common/library/log"
|
||||
bm "go-common/library/net/http/blademaster"
|
||||
"go-common/library/net/http/blademaster/middleware/verify"
|
||||
)
|
||||
|
||||
var (
|
||||
srv *service.Service
|
||||
vfy *verify.Verify
|
||||
)
|
||||
|
||||
// Init init
|
||||
func Init(c *conf.Config) {
|
||||
srv = service.New(c)
|
||||
vfy = verify.New(c.Verify)
|
||||
engine := bm.DefaultServer(c.BM)
|
||||
route(engine)
|
||||
if err := engine.Start(); err != nil {
|
||||
log.Error("bm Start error(%v)", err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func route(e *bm.Engine) {
|
||||
e.Ping(ping)
|
||||
e.Register(register)
|
||||
g := e.Group("/x/dm")
|
||||
{
|
||||
g.GET("/start", vfy.Verify, howToStart)
|
||||
}
|
||||
}
|
||||
|
||||
func ping(c *bm.Context) {
|
||||
if err := srv.Ping(c); err != nil {
|
||||
log.Error("ping error(%v)", err)
|
||||
c.AbortWithStatus(http.StatusServiceUnavailable)
|
||||
}
|
||||
}
|
||||
|
||||
func register(c *bm.Context) {
|
||||
c.JSON(map[string]interface{}{}, nil)
|
||||
}
|
||||
|
||||
// example for http request handler
|
||||
func howToStart(c *bm.Context) {
|
||||
c.String(0, "Golang 大法好 !!!")
|
||||
}
|
35
app/service/live/live-dm/service/BUILD
Normal file
35
app/service/live/live-dm/service/BUILD
Normal file
@ -0,0 +1,35 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["service.go"],
|
||||
importpath = "go-common/app/service/live/live-dm/service",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/service/live/live-dm/conf:go_default_library",
|
||||
"//app/service/live/live-dm/dao:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//app/service/live/live-dm/service/v1:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
33
app/service/live/live-dm/service/service.go
Normal file
33
app/service/live/live-dm/service/service.go
Normal file
@ -0,0 +1,33 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
"go-common/app/service/live/live-dm/dao"
|
||||
)
|
||||
|
||||
// Service struct
|
||||
type Service struct {
|
||||
c *conf.Config
|
||||
dao *dao.Dao
|
||||
}
|
||||
|
||||
// New init
|
||||
func New(c *conf.Config) (s *Service) {
|
||||
s = &Service{
|
||||
c: c,
|
||||
dao: dao.New(c),
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Ping Service
|
||||
func (s *Service) Ping(c context.Context) (err error) {
|
||||
return s.dao.Ping(c)
|
||||
}
|
||||
|
||||
// Close Service
|
||||
func (s *Service) Close() {
|
||||
s.dao.Close()
|
||||
}
|
72
app/service/live/live-dm/service/v1/BUILD
Normal file
72
app/service/live/live-dm/service/v1/BUILD
Normal file
@ -0,0 +1,72 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"dM.go",
|
||||
"dmcheck.go",
|
||||
"getCheckInfo.go",
|
||||
"getDMConf.go",
|
||||
"limit.go",
|
||||
"send.go",
|
||||
],
|
||||
importpath = "go-common/app/service/live/live-dm/service/v1",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/service/live/av/api/liverpc/v1:go_default_library",
|
||||
"//app/service/live/banned_service/api/liverpc/v1:go_default_library",
|
||||
"//app/service/live/live-dm/api/grpc/v1:go_default_library",
|
||||
"//app/service/live/live-dm/conf:go_default_library",
|
||||
"//app/service/live/live-dm/dao:go_default_library",
|
||||
"//app/service/live/live-dm/model:go_default_library",
|
||||
"//library/ecode:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
"//library/net/metadata:go_default_library",
|
||||
"//library/sync/errgroup:go_default_library",
|
||||
"//vendor/github.com/ipipdotnet/ipdb-go:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"//vendor/github.com/satori/go.uuid:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"dm_test.go",
|
||||
"dmcheck_test.go",
|
||||
"getCheckInfo_test.go",
|
||||
"getDMConf_test.go",
|
||||
"limit_test.go",
|
||||
"send_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//app/service/live/live-dm/api/grpc/v1:go_default_library",
|
||||
"//app/service/live/live-dm/conf:go_default_library",
|
||||
"//app/service/live/live-dm/dao:go_default_library",
|
||||
"//library/ecode:go_default_library",
|
||||
"//library/net/metadata:go_default_library",
|
||||
],
|
||||
)
|
201
app/service/live/live-dm/service/v1/dM.go
Normal file
201
app/service/live/live-dm/service/v1/dM.go
Normal file
@ -0,0 +1,201 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
v1pb "go-common/app/service/live/live-dm/api/grpc/v1"
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
"go-common/app/service/live/live-dm/dao"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// DMService struct
|
||||
type DMService struct {
|
||||
conf *conf.Config
|
||||
// optionally add other properties here, such as dao
|
||||
dao *dao.Dao
|
||||
}
|
||||
|
||||
//SendMsg 发送弹幕逻辑参数
|
||||
type SendMsg struct {
|
||||
SendMsgReq *v1pb.SendMsgReq
|
||||
Dmservice *DMService
|
||||
SendMsgResp *v1pb.SendMsgResp
|
||||
UserInfo *dao.UserInfo
|
||||
RoomConf *dao.RoomConf
|
||||
UserBindInfo *dao.UserBindInfo
|
||||
DMconf *dao.DMConf
|
||||
TitleConf *dao.CommentTitle
|
||||
UserScore *dao.UserScore
|
||||
LimitConf *dao.LimitConf
|
||||
}
|
||||
|
||||
//
|
||||
var (
|
||||
reMsg = regexp.MustCompile(`#\s+#`)
|
||||
msgMust = regexp.MustCompile(`(/n)|(\n)`)
|
||||
)
|
||||
|
||||
//NewDMService init
|
||||
func NewDMService(c *conf.Config) (s *DMService) {
|
||||
s = &DMService{
|
||||
conf: c,
|
||||
dao: dao.New(c),
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// SendMsg implementation
|
||||
func (s *DMService) SendMsg(ctx context.Context, req *v1pb.SendMsgReq) (resp *v1pb.SendMsgResp, err error) {
|
||||
sdm := &SendMsg{
|
||||
SendMsgReq: req,
|
||||
Dmservice: s,
|
||||
UserInfo: &dao.UserInfo{
|
||||
MedalInfo: &dao.FansMedalInfo{},
|
||||
},
|
||||
RoomConf: &dao.RoomConf{},
|
||||
UserBindInfo: &dao.UserBindInfo{},
|
||||
TitleConf: &dao.CommentTitle{},
|
||||
DMconf: &dao.DMConf{},
|
||||
UserScore: &dao.UserScore{},
|
||||
LimitConf: &dao.LimitConf{
|
||||
AreaLimit: s.conf.DmRules.AreaLimit,
|
||||
AllUserLimit: s.conf.DmRules.AllUserLimit,
|
||||
LevelLimitStatus: s.conf.DmRules.LevelLimitStatus,
|
||||
LevelLimit: s.conf.DmRules.LevelLimit,
|
||||
RealName: s.conf.DmRules.RealName,
|
||||
PhoneLimit: s.conf.DmRules.PhoneLimit,
|
||||
MsgLength: s.conf.DmRules.MsgLength,
|
||||
DMPercent: s.conf.DmRules.DmPercent,
|
||||
DmNum: s.conf.DmRules.DmNum,
|
||||
DMwhitelist: s.conf.DmRules.DMwhitelist,
|
||||
DMwhitelistID: s.conf.DmRules.DMwhiteListID,
|
||||
},
|
||||
}
|
||||
|
||||
sdm.LimitConf.GetDMCheckConf()
|
||||
|
||||
resp = &v1pb.SendMsgResp{}
|
||||
if req.GetLancer() == nil {
|
||||
req.Lancer = &v1pb.Lancer{}
|
||||
}
|
||||
|
||||
//限制字体大小为25
|
||||
sdm.SendMsgReq.Fontsize = 25
|
||||
|
||||
//特殊字符处理
|
||||
req.Msg = reMsg.ReplaceAllString(req.Msg, " ")
|
||||
sdm.SendMsgReq.Msg = msgMust.ReplaceAllString(req.Msg, "")
|
||||
|
||||
// 发送弹幕的频率控制
|
||||
if err = rateLimit(ctx, sdm); err != nil {
|
||||
if perr, ok := err.(*ecode.Status); ok {
|
||||
resp.Code = int32(perr.Code())
|
||||
resp.LimitMsg = perr.Message()
|
||||
resp.IsLimit = true
|
||||
err = nil
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]", perr.Message(), req.Uid, req.Roomid, req.Msg)
|
||||
dao.InfocDMErr.Info(req.Roomid, req.Uid, req.Msg, perr.Message(),
|
||||
time.Now().Unix(), req.Platform, req.Lancer.Build, req.Lancer.Buvid,
|
||||
req.Lancer.UserAgent, req.Lancer.Refer)
|
||||
return
|
||||
}
|
||||
log.Error("DM limit err:%+v", err)
|
||||
}
|
||||
|
||||
// 获取弹幕禁言检查依赖数据
|
||||
if err = getCheckMsg(ctx, sdm); err != nil {
|
||||
if perr, ok := err.(*ecode.Status); ok {
|
||||
resp.Code = int32(perr.Code())
|
||||
resp.LimitMsg = perr.Message()
|
||||
resp.IsLimit = false
|
||||
err = nil
|
||||
|
||||
return
|
||||
}
|
||||
log.Error("DM get check message err:%+v", err)
|
||||
|
||||
dao.InfocDMErr.Info(req.Roomid, req.Uid, req.Msg, "弹幕禁言检查依赖获取失败",
|
||||
time.Now().Unix(), req.Platform, req.Lancer.Build, req.Lancer.Buvid,
|
||||
req.Lancer.UserAgent, req.Lancer.Refer)
|
||||
}
|
||||
// 弹幕禁言检查
|
||||
if err = checkLegitimacy(ctx, sdm); err != nil {
|
||||
if perr, ok := err.(*ecode.Status); ok {
|
||||
resp.Code = int32(perr.Code())
|
||||
resp.LimitMsg = perr.Message()
|
||||
resp.IsLimit = true
|
||||
err = nil
|
||||
|
||||
return
|
||||
}
|
||||
dao.InfocDMErr.Info(req.Roomid, req.Uid, req.Msg, "弹幕禁言检查失败",
|
||||
time.Now().Unix(), req.Platform, req.Lancer.Build, req.Lancer.Buvid,
|
||||
req.Lancer.UserAgent, req.Lancer.Refer)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取弹幕发送依赖数据
|
||||
if err = getDMconfig(ctx, sdm); err != nil {
|
||||
if perr, ok := err.(*ecode.Status); ok {
|
||||
resp.Code = int32(perr.Code())
|
||||
resp.LimitMsg = perr.Message()
|
||||
resp.IsLimit = false
|
||||
err = nil
|
||||
|
||||
return
|
||||
}
|
||||
dao.InfocDMErr.Info(req.Roomid, req.Uid, req.Msg, "获取弹幕发送依赖数据失败",
|
||||
time.Now().Unix(), req.Platform, req.Lancer.Build, req.Lancer.Buvid,
|
||||
req.Lancer.UserAgent, req.Lancer.Refer)
|
||||
return
|
||||
}
|
||||
|
||||
// 发送弹幕
|
||||
if err = send(ctx, sdm); err != nil {
|
||||
if perr, ok := err.(*ecode.Status); ok {
|
||||
resp.Code = int32(perr.Code())
|
||||
resp.LimitMsg = perr.Message()
|
||||
resp.IsLimit = false
|
||||
err = nil
|
||||
|
||||
return
|
||||
}
|
||||
dao.InfocDMErr.Info(req.Roomid, req.Uid, req.Msg, "弹幕广播失败",
|
||||
time.Now().Unix(), req.Platform, req.Lancer.Build, req.Lancer.Buvid,
|
||||
req.Lancer.UserAgent, req.Lancer.Refer)
|
||||
return
|
||||
}
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]", "弹幕发送成功", req.Uid, req.Roomid, req.Msg)
|
||||
dao.InfocDMSend.Info(req.Roomid, req.Uid, req.Msg, req.Ip, time.Now().Unix(),
|
||||
sdm.DMconf.Color, req.Mode, req.Platform, req.Lancer.Build,
|
||||
req.Lancer.Buvid, req.Lancer.UserAgent, req.Lancer.Refer, req.Lancer.Cookie,
|
||||
req.Msgtype)
|
||||
return
|
||||
}
|
||||
|
||||
// GetHistory implementation
|
||||
func (s *DMService) GetHistory(ctx context.Context, req *v1pb.HistoryReq) (resp *v1pb.HistoryResp, err error) {
|
||||
resp = &v1pb.HistoryResp{}
|
||||
rest, err := s.dao.GetHistoryData(ctx, req.Roomid)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
resp.Admin = make([]string, 0, 10)
|
||||
resp.Room = make([]string, 0, 10)
|
||||
resp.Admin = append(resp.Admin, rest["admin"]...)
|
||||
resp.Room = append(resp.Room, rest["room"]...)
|
||||
return
|
||||
}
|
||||
|
||||
func lancer(sdm *SendMsg, reason string) {
|
||||
req := sdm.SendMsgReq
|
||||
dao.InfocDMErr.Info(req.Roomid, req.Uid, req.Msg, reason,
|
||||
time.Now().Unix(), req.Platform, req.Lancer.Build, req.Lancer.Buvid,
|
||||
req.Lancer.UserAgent, req.Lancer.Refer)
|
||||
}
|
40
app/service/live/live-dm/service/v1/dm_test.go
Normal file
40
app/service/live/live-dm/service/v1/dm_test.go
Normal file
@ -0,0 +1,40 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
v1pb "go-common/app/service/live/live-dm/api/grpc/v1"
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
"go-common/app/service/live/live-dm/dao"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func init() {
|
||||
dir, _ := filepath.Abs("../../cmd/test.toml")
|
||||
flag.Set("conf", dir)
|
||||
var err error
|
||||
if err = conf.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
dao.InitAPI()
|
||||
dao.InitGrpc(conf.Conf)
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestDMService_SendMsg
|
||||
func TestDMService_SendMsg(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestGetHistory
|
||||
func TestGetHistory(t *testing.T) {
|
||||
req := &v1pb.HistoryReq{
|
||||
Roomid: 460828,
|
||||
}
|
||||
|
||||
s := &DMService{
|
||||
conf: conf.Conf,
|
||||
dao: dao.New(conf.Conf),
|
||||
}
|
||||
s.GetHistory(context.TODO(), req)
|
||||
}
|
554
app/service/live/live-dm/service/v1/dmcheck.go
Normal file
554
app/service/live/live-dm/service/v1/dmcheck.go
Normal file
@ -0,0 +1,554 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/ipipdotnet/ipdb-go"
|
||||
|
||||
avService "go-common/app/service/live/av/api/liverpc/v1"
|
||||
bannedService "go-common/app/service/live/banned_service/api/liverpc/v1"
|
||||
"go-common/app/service/live/live-dm/dao"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
"go-common/library/net/metadata"
|
||||
"go-common/library/sync/errgroup"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
//检查弹幕合法性
|
||||
func checkLegitimacy(ctx context.Context, sdm *SendMsg) error {
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
//防止竞态条件,透传mid以及userip
|
||||
if md, ok := metadata.FromContext(ctx); ok {
|
||||
md[metadata.Mid] = sdm.SendMsgReq.Uid
|
||||
md[metadata.RemoteIP] = sdm.SendMsgReq.Ip
|
||||
}
|
||||
//全局禁言检查
|
||||
g.Go(func() error { return globalRestriction(ctx, sdm) })
|
||||
//付费直播检查
|
||||
g.Go(func() error { return paidRoomInspection(ctx, sdm) })
|
||||
//弹幕长度检查
|
||||
g.Go(func() error { return messageLenCheck(ctx, sdm) })
|
||||
//房间配置禁言检查
|
||||
g.Go(func() error { return roomInfoCheck(ctx, sdm) })
|
||||
// 房间禁言名单
|
||||
g.Go(func() error { return roomBluckList(ctx, sdm) })
|
||||
// 主播过滤用户
|
||||
g.Go(func() error { return anchorFilterUser(ctx, sdm) })
|
||||
// 主播过滤内容
|
||||
g.Go(func() error { return anchorFilterMsg(ctx, sdm) })
|
||||
// 用户绑定信息判断是否禁言
|
||||
g.Go(func() error { return authenticationAuthority(ctx, sdm) })
|
||||
// 用户区域检查
|
||||
if sdm.LimitConf.AreaLimit {
|
||||
g.Go(func() error { return userAreaLive(sdm) })
|
||||
}
|
||||
//弹幕内容检查
|
||||
g.Go(func() error { return messageCheck(ctx, sdm) })
|
||||
// 调用真实接口判断,弹幕是否可以广播
|
||||
g.Go(func() error { return canBroadCastMsg(ctx, sdm) })
|
||||
//2019 拜年祭白名单
|
||||
roomid := strconv.FormatInt(sdm.SendMsgReq.Roomid, 10)
|
||||
if sdm.LimitConf.DMwhitelist && sdm.Dmservice.conf.BNJRoomList[roomid] {
|
||||
g.Go(func() error { return dmWhiteList(ctx, sdm) })
|
||||
}
|
||||
|
||||
return g.Wait()
|
||||
}
|
||||
|
||||
//DMWhiteList 拜年祭白名单
|
||||
func dmWhiteList(ctx context.Context, sdm *SendMsg) error {
|
||||
if sdm.LimitConf.DMwhitelistID == "ID-0" {
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]",
|
||||
"非拜年祭白名单用户", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg)
|
||||
lancer(sdm, "非拜年祭白名单用户")
|
||||
return ecode.Error(0, "w")
|
||||
}
|
||||
|
||||
key := fmt.Sprintf("%s_%d", sdm.LimitConf.DMwhitelistID, sdm.SendMsgReq.Uid)
|
||||
if isWhite := sdm.Dmservice.dao.IsWhietListUID(ctx, key); isWhite {
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]",
|
||||
"非拜年祭白名单用户", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg)
|
||||
lancer(sdm, "非拜年祭白名单用户")
|
||||
return ecode.Error(0, "w")
|
||||
}
|
||||
|
||||
//globalRestriction 全局禁言检查
|
||||
func globalRestriction(ctx context.Context, sdm *SendMsg) error {
|
||||
if sdm.LimitConf.AllUserLimit {
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]",
|
||||
"开启全局禁言", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg)
|
||||
|
||||
lancer(sdm, "开启全局禁言")
|
||||
return ecode.Error(0, "系统正在维护")
|
||||
}
|
||||
|
||||
if sdm.UserInfo.UserLever <= sdm.LimitConf.LevelLimit && sdm.LimitConf.LevelLimitStatus {
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s, limitLevel:%d, userLever:%d]",
|
||||
"全局等级禁言", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg, sdm.LimitConf.LevelLimit, sdm.UserInfo.UserLever)
|
||||
|
||||
lancer(sdm, "开启全局等级禁言")
|
||||
return ecode.Error(0, "系统正在维护")
|
||||
}
|
||||
|
||||
//全站禁言
|
||||
req := &bannedService.SiteBlockMngIsBlockUserReq{
|
||||
Tuid: sdm.SendMsgReq.Uid,
|
||||
}
|
||||
|
||||
resp, err := dao.BannedServiceClient.V1SiteBlockMng.IsBlockUser(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: banned_service V1SiteBlockMng IsBlockUser err : %+v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if resp.Code != 0 {
|
||||
log.Error("DM: banned_service V1SiteBlockMng IsBlockUser err code: %d", resp.Code)
|
||||
return nil
|
||||
}
|
||||
if resp.Data.IsBlock {
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]",
|
||||
"直播黑名单用户", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg)
|
||||
lancer(sdm, "直播黑名单用户")
|
||||
return ecode.Error(0, "你被禁言啦")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
//PaidRoomInspection 付费直播检查
|
||||
func paidRoomInspection(ctx context.Context, sdm *SendMsg) error {
|
||||
req := &avService.PayLiveLiveValidateReq{
|
||||
RoomId: sdm.SendMsgReq.Roomid,
|
||||
Platform: "grpc",
|
||||
}
|
||||
// if md, ok := metadata.FromContext(ctx); ok {
|
||||
// md[metadata.Mid] = sdm.SendMsgReq.Uid
|
||||
// md[metadata.RemoteIP] = sdm.SendMsgReq.Ip
|
||||
// }
|
||||
resp, err := dao.AvServiceClient.V1PayLive.LiveValidate(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: V1PayLive err: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if resp.Code == 5001 {
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]",
|
||||
"付费直播间", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg)
|
||||
|
||||
lancer(sdm, "付费直播间")
|
||||
return ecode.Error(-102, "非常抱歉,本场直播需要购票,即可参与互动")
|
||||
} else if resp.Code == 5003 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if resp.Code != 0 {
|
||||
log.Error("DM: V1OayLive error code: %d", resp.Code)
|
||||
|
||||
lancer(sdm, "付费直播间")
|
||||
return ecode.Error(-102, "非常抱歉,本场直播需要购票,即可参与互动")
|
||||
}
|
||||
|
||||
if resp.Data.Permission != 1 {
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]",
|
||||
"付费直播间", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg)
|
||||
|
||||
lancer(sdm, "付费直播间")
|
||||
return ecode.Error(-102, "非常抱歉,本场直播需要购票,即可参与互动")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//MessageCheck 弹幕内容检查
|
||||
func messageCheck(ctx context.Context, sdm *SendMsg) error {
|
||||
//命中等级大于等于20
|
||||
if sdm.UserScore.MsgLevel >= 20 {
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]",
|
||||
"弹幕内容非法", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg)
|
||||
|
||||
lancer(sdm, "内容非法")
|
||||
return ecode.Error(0, "内容非法")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//MessageLenCheck 弹幕长度检查
|
||||
func messageLenCheck(ctx context.Context, sdm *SendMsg) error {
|
||||
ml := len([]rune(sdm.SendMsgReq.Msg))
|
||||
// 小于默认长度 允许发送
|
||||
if ml < sdm.LimitConf.MsgLength {
|
||||
return nil
|
||||
}
|
||||
// 弹幕长度
|
||||
if ml <= int(sdm.DMconf.Length) {
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s, msgLength:%d, limitLength:%d]",
|
||||
"超出限制长度", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg, ml, sdm.DMconf.Length)
|
||||
lancer(sdm, "超出限制长度")
|
||||
return ecode.Error(-500, "超出限制长度")
|
||||
}
|
||||
|
||||
//RoomInfoCheck 房间配置禁言检查
|
||||
func roomInfoCheck(ctx context.Context, sdm *SendMsg) error {
|
||||
if sdm.SendMsgReq.Uid == sdm.RoomConf.UID ||
|
||||
sdm.UserInfo.RoomAdmin {
|
||||
return nil
|
||||
}
|
||||
//查询房间禁言
|
||||
req := &bannedService.SilentGetRoomSilentReq{
|
||||
RoomId: sdm.SendMsgReq.Roomid,
|
||||
}
|
||||
resp, err := dao.BannedServiceClient.V1Silent.GetRoomSilent(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: banned_service GetRoomSilent err: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if resp.Code != 0 {
|
||||
log.Error("DM: banned_service GetRoomSilent err code: %d", resp.Code)
|
||||
return nil
|
||||
}
|
||||
|
||||
switch resp.Data.Type {
|
||||
case "level":
|
||||
// 等级限制
|
||||
if resp.Data.Level < sdm.UserInfo.UserLever {
|
||||
return nil
|
||||
}
|
||||
// 老爷免疫
|
||||
if sdm.UserInfo.Vip != 0 || sdm.UserInfo.Svip != 0 {
|
||||
return nil
|
||||
}
|
||||
// 守护免疫
|
||||
if sdm.UserInfo.PrivilegeType != 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var errm string
|
||||
if resp.Data.Second == -1 {
|
||||
errm = "本场直播结束后解除~"
|
||||
} else {
|
||||
errm = strconv.FormatInt(resp.Data.Second/60, 10) + "分钟后解除~"
|
||||
}
|
||||
em := fmt.Sprintf("主播对UL %d以下开启了禁言,%s", resp.Data.Level, errm)
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]",
|
||||
em, sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg)
|
||||
lancer(sdm, "播主开启等级禁言")
|
||||
|
||||
return ecode.Error(-403, em)
|
||||
case "medal":
|
||||
|
||||
var errm string
|
||||
if resp.Data.Second == -1 {
|
||||
errm = "本场直播结束后解除~"
|
||||
} else {
|
||||
errm = strconv.FormatInt(resp.Data.Second/60, 10) + "分钟后解除~"
|
||||
}
|
||||
em := fmt.Sprintf("主播对粉丝勋章%d以下开启了禁言,%s", resp.Data.Level, errm)
|
||||
|
||||
//佩戴勋章不一致
|
||||
if sdm.RoomConf.UID != sdm.UserInfo.MedalInfo.RUID {
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]",
|
||||
em, sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg)
|
||||
lancer(sdm, "播主开启粉丝勋章限制")
|
||||
|
||||
return ecode.Error(-403, em)
|
||||
}
|
||||
// 勋章等级免疫
|
||||
if resp.Data.Level < sdm.UserInfo.MedalInfo.MedalLevel {
|
||||
return nil
|
||||
}
|
||||
// 守护免疫(等级限制)
|
||||
pt := sdm.UserInfo.PrivilegeType
|
||||
if pt >= 1 && pt <= 2 {
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]",
|
||||
em, sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg)
|
||||
lancer(sdm, "播主开启粉丝勋章限制")
|
||||
|
||||
return ecode.Error(-403, em)
|
||||
case "member":
|
||||
//守护免疫(总督免疫)
|
||||
if sdm.UserInfo.PrivilegeType == 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var errm string
|
||||
if resp.Data.Second == -1 {
|
||||
errm = "本场直播结束后解除~"
|
||||
} else {
|
||||
errm = strconv.FormatInt(resp.Data.Second/60, 10) + "分钟后解除~"
|
||||
}
|
||||
em := fmt.Sprintf("主播对全体用户开启了禁言,%s", errm)
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]",
|
||||
em, sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg)
|
||||
lancer(sdm, "播开启房间全体禁言")
|
||||
|
||||
return ecode.Error(-403, em)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//RoomBluckList 房间禁言名单
|
||||
func roomBluckList(ctx context.Context, sdm *SendMsg) error {
|
||||
req := &bannedService.SilentMngIsBlockUserReq{
|
||||
Uid: sdm.SendMsgReq.Uid,
|
||||
Roomid: sdm.SendMsgReq.Roomid,
|
||||
Type: 1,
|
||||
}
|
||||
|
||||
resp, err := dao.BannedServiceClient.V1SilentMng.IsBlockUser(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: BannedService IsBlockUser err: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if resp.Code != 0 {
|
||||
log.Error("DM: BannedService IsBlockUser err code: %d", resp.Code)
|
||||
return nil
|
||||
}
|
||||
if resp.Data.IsBlockUser {
|
||||
if sdm.UserInfo.PrivilegeType == 1 {
|
||||
return nil
|
||||
}
|
||||
tm := time.Unix(resp.Data.BlockEndTime, 0)
|
||||
ms := "你在本房间被禁言至 " + tm.Format("2006-01-02 15:04:05")
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]",
|
||||
"主播禁言名单", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg)
|
||||
lancer(sdm, "播主禁言名单")
|
||||
|
||||
return ecode.Error(1003, ms)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//AnchorFilterUser 主播过滤用户
|
||||
func anchorFilterUser(ctx context.Context, sdm *SendMsg) error {
|
||||
if sdm.RoomConf.RoomShield != 1 {
|
||||
return nil
|
||||
}
|
||||
req := &bannedService.ShieldMngIsShieldUserReq{
|
||||
Uid: sdm.RoomConf.UID,
|
||||
ShieldUid: sdm.SendMsgReq.Uid,
|
||||
}
|
||||
resp, err := dao.BannedServiceClient.V1ShieldMng.IsShieldUser(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: BannedService IsShieldUser err: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if resp.Code != 0 {
|
||||
log.Error("DM: BannedService IsShieldUser err code: %d", resp.Code)
|
||||
return nil
|
||||
}
|
||||
if resp.Data.IsShieldUser {
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]",
|
||||
"主播过滤用户", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg)
|
||||
lancer(sdm, "被播主过滤的用户")
|
||||
|
||||
return ecode.Error(0, "u")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//AnchorFilterMsg 主播过滤内容
|
||||
func anchorFilterMsg(ctx context.Context, sdm *SendMsg) error {
|
||||
if sdm.RoomConf.RoomShield != 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
req := &bannedService.ShieldIsShieldContentReq{
|
||||
Uid: sdm.RoomConf.UID,
|
||||
Content: sdm.SendMsgReq.Msg,
|
||||
}
|
||||
resp, err := dao.BannedServiceClient.V1Shield.IsShieldContent(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: BannedService IsShieldContent err: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if resp.Code != 0 {
|
||||
log.Error("DM: BannedService IsShieldContent err code: %d", resp.Code)
|
||||
return nil
|
||||
}
|
||||
if resp.Data.IsShieldContent {
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]",
|
||||
"主播过滤内容", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg)
|
||||
lancer(sdm, "被播主过滤的弹幕内容")
|
||||
|
||||
return ecode.Error(0, "k")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//CanBroadCastMsg 调用真实接口判断,弹幕是否可以广播
|
||||
func canBroadCastMsg(ctx context.Context, sdm *SendMsg) error {
|
||||
req := &bannedService.AdminSilentGetShieldRuleReq{
|
||||
Roomid: sdm.SendMsgReq.Roomid,
|
||||
}
|
||||
resp, err := dao.BannedServiceClient.V1AdminSilent.GetShieldRule(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Cause(err) != context.Canceled {
|
||||
log.Error("DM: BannedService GetShieldRule err: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if resp.Code != 0 {
|
||||
log.Error("DM: BannedService GetShieldRule err code: %d", resp.Code)
|
||||
return nil
|
||||
}
|
||||
|
||||
if sdm.UserScore.UserScore >= resp.Data.RealScore &&
|
||||
sdm.UserScore.MsgAI <= resp.Data.AiScore {
|
||||
return nil
|
||||
}
|
||||
|
||||
if sdm.UserScore.UserScore < resp.Data.RealScore {
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s, UserScore: %d, RealScore: %d]",
|
||||
"用户真实分拦截", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg, sdm.UserScore.UserScore, resp.Data.RealScore)
|
||||
lancer(sdm, "用户真实分拦截")
|
||||
}
|
||||
if sdm.UserScore.MsgAI > resp.Data.AiScore {
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s MsgAI: %d, AiScore: %d]",
|
||||
"弹幕AI分拦截", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg, sdm.UserScore.MsgAI, resp.Data.AiScore)
|
||||
lancer(sdm, "弹幕AI分拦截")
|
||||
}
|
||||
|
||||
return ecode.Error(0, "fire")
|
||||
}
|
||||
|
||||
//AuthenticationAuthority 用户绑定信息判断是否禁言
|
||||
func authenticationAuthority(ctx context.Context, sdm *SendMsg) error {
|
||||
if sdm.LimitConf.RealName {
|
||||
if 1 != sdm.UserBindInfo.Identification {
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]",
|
||||
"未实名认证", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg)
|
||||
lancer(sdm, "未实名认证")
|
||||
|
||||
return ecode.Error(0, "实名认证才可以发言")
|
||||
}
|
||||
}
|
||||
|
||||
mvf := sdm.UserBindInfo.MobileVerify
|
||||
if sdm.LimitConf.PhoneLimit {
|
||||
if mvf != 1 {
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s]",
|
||||
"未实绑定手机", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg)
|
||||
lancer(sdm, "未绑定手机")
|
||||
|
||||
return ecode.Error(1001, "根据国家实名制认证的相关要求,您需要绑定手机号,才能继续进行操作")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//UserArea 用户区域判断
|
||||
// func userArea(ctx context.Context, sdm *SendMsg) error {
|
||||
// var ip = strings.Split(sdm.SendMsgReq.Ip, ":")
|
||||
// req := &locationService.InfoReq{
|
||||
// Addr: ip[0],
|
||||
// }
|
||||
// resp, err := dao.LcClient.Info(ctx, req)
|
||||
// if err != nil {
|
||||
// log.Error("DM: 主站区域查询接口失败 ERR: %v ip:%s", err, sdm.SendMsgReq.Ip)
|
||||
// return nil
|
||||
// }
|
||||
// if resp.Country == "中国" || resp.Country == "局域网" {
|
||||
// return nil
|
||||
// }
|
||||
// log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s, 用户IP:%s 用户区域:%s]",
|
||||
// "用户所在区域无法发言", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
// sdm.SendMsgReq.Msg, sdm.SendMsgReq.Ip, resp.Country)
|
||||
|
||||
// return &errPb.Error{
|
||||
// ErrCode: 0,
|
||||
// ErrMessage: "你所在的地区暂无法发言",
|
||||
// }
|
||||
// }
|
||||
|
||||
//userAreaLive 用户区域判断
|
||||
func userAreaLive(sdm *SendMsg) error {
|
||||
var cityInfo *ipdb.CityInfo
|
||||
var err error
|
||||
|
||||
for _, v := range sdm.SendMsgReq.Ip {
|
||||
if string(v) == "." {
|
||||
cityInfo, err = dao.IP4db.FindInfo(sdm.SendMsgReq.Ip, "CN")
|
||||
break
|
||||
} else if string(v) == ":" {
|
||||
cityInfo, err = dao.IP6db.FindInfo(sdm.SendMsgReq.Ip, "CN")
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if cityInfo == nil {
|
||||
log.Error("DM: ip解析失败: %s", sdm.SendMsgReq.Ip)
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
log.Error("IPdb errr:%+v", err)
|
||||
return err
|
||||
}
|
||||
if cityInfo.CountryName == "中国" || cityInfo.CountryName == "局域网" {
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Info("LIMITDM, reason: %s, [detail: uid:%d, roomid:%d, msg:%s, 用户IP:%s 用户区域:%s]",
|
||||
"用户所在区域无法发言", sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid,
|
||||
sdm.SendMsgReq.Msg, sdm.SendMsgReq.Ip, cityInfo.CountryName)
|
||||
lancer(sdm, "用户区域限制")
|
||||
|
||||
return ecode.Error(0, "你所在的地区暂无法发言")
|
||||
}
|
422
app/service/live/live-dm/service/v1/dmcheck_test.go
Normal file
422
app/service/live/live-dm/service/v1/dmcheck_test.go
Normal file
@ -0,0 +1,422 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
v1pb "go-common/app/service/live/live-dm/api/grpc/v1"
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
"go-common/app/service/live/live-dm/dao"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/net/metadata"
|
||||
)
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -race -run TestCheckLegitimacy
|
||||
func TestCheckLegitimacy(t *testing.T) {
|
||||
s := &SendMsg{
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Uid: 1877309,
|
||||
Roomid: 5392,
|
||||
Ip: "115.239.211.112",
|
||||
Msg: "6666",
|
||||
Rnd: "1000",
|
||||
Fontsize: 15,
|
||||
Mode: 1,
|
||||
Platform: "ios",
|
||||
Msgtype: 0,
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
UserInfo: &dao.UserInfo{
|
||||
UserLever: 100,
|
||||
MedalInfo: &dao.FansMedalInfo{},
|
||||
},
|
||||
RoomConf: &dao.RoomConf{
|
||||
UID: 158807,
|
||||
RoomID: 5392,
|
||||
Anchor: "沢奇Sawaki",
|
||||
},
|
||||
UserBindInfo: &dao.UserBindInfo{
|
||||
Uname: "Bili_111",
|
||||
URank: 1000,
|
||||
},
|
||||
TitleConf: &dao.CommentTitle{},
|
||||
DMconf: &dao.DMConf{
|
||||
Mode: 6,
|
||||
Color: 5555,
|
||||
Length: 20,
|
||||
},
|
||||
UserScore: &dao.UserScore{
|
||||
UserScore: 90,
|
||||
},
|
||||
}
|
||||
if err := checkLegitimacy(context.TODO(), s); err != nil {
|
||||
fmt.Print("####\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestGlobalRestriction
|
||||
func TestGlobalRestriction(t *testing.T) {
|
||||
s := &SendMsg{
|
||||
UserInfo: &dao.UserInfo{
|
||||
UserLever: 1,
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
}
|
||||
if err := globalRestriction(context.TODO(), s); err != nil {
|
||||
if err != ecode.DMUserLevel {
|
||||
t.Error("全局禁言检查错误:", err)
|
||||
}
|
||||
}
|
||||
s.Dmservice.conf.DmRules.LevelLimit = 10
|
||||
s.UserInfo.UserLever = 5
|
||||
if err := globalRestriction(context.TODO(), s); err != nil {
|
||||
if err != ecode.DMUserLevel {
|
||||
t.Error("全局等级禁言检查错误:", err)
|
||||
}
|
||||
}
|
||||
s.Dmservice.conf.DmRules.AllUserLimit = true
|
||||
if err := globalRestriction(context.TODO(), s); err != nil {
|
||||
if err != ecode.DMallUser {
|
||||
t.Error("全体禁言检查错误:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestPaidRoomInspection
|
||||
func TestPaidRoomInspection(t *testing.T) {
|
||||
ctx := metadata.NewContext(context.TODO(), metadata.MD{})
|
||||
var s = &SendMsg{
|
||||
UserInfo: &dao.UserInfo{
|
||||
UserLever: 1,
|
||||
},
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Uid: 111,
|
||||
Roomid: 460460,
|
||||
Ip: "115.239.211.112",
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
}
|
||||
if err := paidRoomInspection(ctx, s); err != nil {
|
||||
if err != ecode.PayLive {
|
||||
t.Error("付费检查失败")
|
||||
}
|
||||
}
|
||||
s.SendMsgReq.Uid = 123
|
||||
if err := paidRoomInspection(ctx, s); err != nil {
|
||||
t.Error("付费检查失败")
|
||||
}
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestDmcheck_MessageCheck
|
||||
func TestDmcheck_MessageCheck(t *testing.T) {
|
||||
s := &SendMsg{
|
||||
UserScore: &dao.UserScore{
|
||||
MsgLevel: 30,
|
||||
},
|
||||
SendMsgReq: &v1pb.SendMsgReq{},
|
||||
}
|
||||
if err := messageCheck(context.TODO(), s); err != nil {
|
||||
if err != ecode.FilterLimit {
|
||||
t.Error("弹幕内容检查失败 Level 30")
|
||||
}
|
||||
}
|
||||
s.UserScore.MsgLevel = 10
|
||||
if err := messageCheck(context.TODO(), s); err != nil {
|
||||
t.Error("弹幕内容检查失败 Level 10")
|
||||
}
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestDmcheck_MessageLenCheck
|
||||
func TestDmcheck_MessageLenCheck(t *testing.T) {
|
||||
s := &SendMsg{
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Msg: "6666",
|
||||
},
|
||||
DMconf: &dao.DMConf{Length: 30},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
}
|
||||
if err := messageLenCheck(context.TODO(), s); err != nil {
|
||||
t.Error("弹幕长度检查失败 msg:6666")
|
||||
}
|
||||
s.SendMsgReq.Msg = "666666666666666666666"
|
||||
if err := messageLenCheck(context.TODO(), s); err != nil {
|
||||
t.Error("弹幕长度检查失败 msglength:21")
|
||||
}
|
||||
|
||||
s.SendMsgReq.Msg = "一一一一一一一一一一一一一一一一一一一一一"
|
||||
s.DMconf.Length = 20
|
||||
if err := messageLenCheck(context.TODO(), s); err != nil {
|
||||
if err != ecode.MsgLengthLimit {
|
||||
t.Error("弹幕长度检查失败 msglength:21个一")
|
||||
}
|
||||
}
|
||||
|
||||
s.SendMsgReq.Msg = "一一一一一一一一一一一一一一一一一一一一一"
|
||||
s.DMconf.Length = 30
|
||||
if err := messageLenCheck(context.TODO(), s); err != nil {
|
||||
t.Error("弹幕长度检查失败 msglength:21个一 长度限制30")
|
||||
}
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestDmcheck_RoomInfoCheck
|
||||
func TestDmcheck_RoomInfoCheck(t *testing.T) {
|
||||
s := &SendMsg{
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Msg: "6666",
|
||||
Roomid: 460758,
|
||||
Uid: 222,
|
||||
},
|
||||
DMconf: &dao.DMConf{
|
||||
Length: 30,
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
RoomConf: &dao.RoomConf{
|
||||
UID: 111,
|
||||
},
|
||||
UserInfo: &dao.UserInfo{
|
||||
RoomAdmin: false,
|
||||
UserLever: 10,
|
||||
},
|
||||
}
|
||||
if err := roomInfoCheck(context.TODO(), s); err != nil {
|
||||
if err == ecode.RoomAllLimit && err == ecode.RoomMedalLimit &&
|
||||
err == ecode.RoomLeverLimit {
|
||||
t.Error("房间禁言检查错误")
|
||||
}
|
||||
}
|
||||
s.UserInfo.PrivilegeType = 1
|
||||
|
||||
if err := roomInfoCheck(context.TODO(), s); err != nil {
|
||||
t.Error("总督禁言检查错误")
|
||||
}
|
||||
|
||||
s.UserInfo.PrivilegeType = 2
|
||||
|
||||
if err := roomInfoCheck(context.TODO(), s); err != nil {
|
||||
if err == ecode.RoomAllLimit && err == ecode.RoomMedalLimit &&
|
||||
err == ecode.RoomLeverLimit {
|
||||
t.Error("房间禁言检查错误")
|
||||
}
|
||||
}
|
||||
s.UserInfo.PrivilegeType = 0
|
||||
s.UserInfo.UserLever = 6
|
||||
if err := roomInfoCheck(context.TODO(), s); err != nil {
|
||||
fmt.Print("11111", err)
|
||||
if err == ecode.RoomAllLimit && err == ecode.RoomMedalLimit &&
|
||||
err == ecode.RoomLeverLimit {
|
||||
t.Error("房间禁言检查错误")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestDmcheck_RoomBluckList
|
||||
func TestDmcheck_RoomBluckList(t *testing.T) {
|
||||
s := &SendMsg{
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Msg: "666",
|
||||
Roomid: 460758,
|
||||
Uid: 111,
|
||||
},
|
||||
DMconf: &dao.DMConf{
|
||||
Length: 30,
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
RoomConf: &dao.RoomConf{
|
||||
UID: 110000298,
|
||||
RoomShield: 1,
|
||||
},
|
||||
UserInfo: &dao.UserInfo{
|
||||
RoomAdmin: false,
|
||||
UserLever: 10,
|
||||
},
|
||||
}
|
||||
if err := roomBluckList(context.TODO(), s); err != nil {
|
||||
t.Error("房间黑名单检查错误", err)
|
||||
}
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestDmcheck_AnchorFilterMsg
|
||||
func TestDmcheck_AnchorFilterMsg(t *testing.T) {
|
||||
s := &SendMsg{
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Msg: "666",
|
||||
Roomid: 460758,
|
||||
Uid: 222,
|
||||
},
|
||||
DMconf: &dao.DMConf{
|
||||
Length: 30,
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
RoomConf: &dao.RoomConf{
|
||||
UID: 110000298,
|
||||
RoomShield: 1,
|
||||
},
|
||||
UserInfo: &dao.UserInfo{
|
||||
RoomAdmin: false,
|
||||
UserLever: 10,
|
||||
},
|
||||
}
|
||||
if err := anchorFilterMsg(context.TODO(), s); err != nil {
|
||||
if err != ecode.ShieldContent {
|
||||
t.Error("主播屏蔽过滤词失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestDmcheck_AnchorFilterUser
|
||||
func TestDmcheck_AnchorFilterUser(t *testing.T) {
|
||||
s := &SendMsg{
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Msg: "666",
|
||||
Roomid: 460758,
|
||||
Uid: 222,
|
||||
},
|
||||
DMconf: &dao.DMConf{
|
||||
Length: 30,
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
RoomConf: &dao.RoomConf{
|
||||
UID: 110000298,
|
||||
RoomShield: 1,
|
||||
},
|
||||
UserInfo: &dao.UserInfo{
|
||||
RoomAdmin: false,
|
||||
UserLever: 10,
|
||||
},
|
||||
}
|
||||
if err := anchorFilterUser(context.TODO(), s); err != nil {
|
||||
if err != ecode.ShieldContent {
|
||||
t.Error("主播屏蔽过滤用户失败")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestDmcheck_CanBroadCastMsg
|
||||
func TestDmcheck_CanBroadCastMsg(t *testing.T) {
|
||||
s := &SendMsg{
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Msg: "666",
|
||||
Roomid: 460758,
|
||||
Uid: 222,
|
||||
},
|
||||
DMconf: &dao.DMConf{
|
||||
Length: 30,
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
RoomConf: &dao.RoomConf{
|
||||
UID: 110000298,
|
||||
RoomShield: 1,
|
||||
},
|
||||
UserInfo: &dao.UserInfo{
|
||||
RoomAdmin: false,
|
||||
UserLever: 10,
|
||||
},
|
||||
UserScore: &dao.UserScore{
|
||||
UserScore: 10,
|
||||
MsgAI: 0,
|
||||
},
|
||||
}
|
||||
if err := canBroadCastMsg(context.TODO(), s); err != nil {
|
||||
t.Error("真实分服务错误")
|
||||
}
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestDmcheck_AuthenticationAuthority
|
||||
func TestDmcheck_AuthenticationAuthority(t *testing.T) {
|
||||
var s = &SendMsg{
|
||||
UserInfo: &dao.UserInfo{
|
||||
UserLever: 1,
|
||||
},
|
||||
UserBindInfo: &dao.UserBindInfo{
|
||||
Identification: 0,
|
||||
MobileVerify: 0,
|
||||
},
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Uid: 111,
|
||||
Roomid: 460460,
|
||||
Ip: "115.239.211.112",
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
}
|
||||
if err := authenticationAuthority(context.TODO(), s); err != nil {
|
||||
if err != ecode.RealName {
|
||||
t.Error("实名认证检查失败")
|
||||
}
|
||||
}
|
||||
s.UserBindInfo.Identification = 1
|
||||
if err := authenticationAuthority(context.TODO(), s); err != nil {
|
||||
if err != ecode.PhoneBind {
|
||||
t.Error("手机绑定检查失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestDmcheck_UserArea
|
||||
// func TestDmcheck_UserArea(t *testing.T) {
|
||||
// var s = &SendMsg{
|
||||
// UserInfo: &dao.UserInfo{
|
||||
// UserLever: 1,
|
||||
// },
|
||||
// SendMsgReq: &v1pb.SendMsgReq{
|
||||
// Uid: 111,
|
||||
// Roomid: 460460,
|
||||
// Ip: "115.239.211.112",
|
||||
// },
|
||||
// Dmservice: &DMService{
|
||||
// conf: conf.Conf,
|
||||
// },
|
||||
// }
|
||||
// if err := userArea(context.TODO(), s); err != nil {
|
||||
// t.Error("区域判断出错")
|
||||
// }
|
||||
// s.SendMsgReq.Ip = "198.11.179.19"
|
||||
// if err := userArea(context.TODO(), s); err != nil {
|
||||
// if err != ecode.CountryLimit {
|
||||
// t.Error("区域判断出错 美国")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
//group=fat1 DEPLOY_ENV=uat go test -run TestDmcheck_userAreaLive
|
||||
func TestDmcheck_userAreaLive(t *testing.T) {
|
||||
dao.InitIPdb()
|
||||
var s = &SendMsg{
|
||||
UserInfo: &dao.UserInfo{
|
||||
UserLever: 1,
|
||||
},
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Uid: 111,
|
||||
Roomid: 460460,
|
||||
Ip: "115.239.211.112",
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
}
|
||||
err := userAreaLive(s)
|
||||
if err != nil {
|
||||
t.Error("#####", err)
|
||||
}
|
||||
}
|
66
app/service/live/live-dm/service/v1/getCheckInfo.go
Normal file
66
app/service/live/live-dm/service/v1/getCheckInfo.go
Normal file
@ -0,0 +1,66 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/library/sync/errgroup"
|
||||
)
|
||||
|
||||
//getCheckMsg 获取弹幕检查信息
|
||||
func getCheckMsg(ctx context.Context, sdm *SendMsg) error {
|
||||
|
||||
g, ctxn := errgroup.WithContext(ctx)
|
||||
|
||||
//获取弹幕配置
|
||||
g.Go(func() error {
|
||||
uid := sdm.SendMsgReq.Uid
|
||||
roomid := sdm.SendMsgReq.Roomid
|
||||
return sdm.DMconf.Get(ctxn, uid, roomid, sdm.Dmservice.conf)
|
||||
})
|
||||
//获取用户等级经验 TODO
|
||||
g.Go(func() error {
|
||||
return sdm.UserInfo.Get(ctxn, sdm.SendMsgReq.Uid)
|
||||
})
|
||||
//获取用户老爷等级
|
||||
g.Go(func() error {
|
||||
return sdm.UserInfo.GetVipInfo(ctxn, sdm.SendMsgReq.Uid)
|
||||
})
|
||||
//获取房间,大航海,房管信息
|
||||
g.Go(func() error {
|
||||
return getRoomConf(ctxn, sdm)
|
||||
})
|
||||
//获取用户绑定信息
|
||||
g.Go(func() error {
|
||||
return sdm.UserBindInfo.Get(ctxn, sdm.SendMsgReq.Uid)
|
||||
})
|
||||
//获取用户粉丝勋章信息
|
||||
g.Go(func() error {
|
||||
return sdm.UserInfo.MedalInfo.GetFansMedal(ctxn, sdm.SendMsgReq.Uid)
|
||||
})
|
||||
|
||||
//获取弹幕真实分
|
||||
g.Go(func() error {
|
||||
return sdm.UserScore.GetMsgScore(ctxn, sdm.SendMsgReq.Msg)
|
||||
})
|
||||
//获取用户真实分
|
||||
g.Go(func() error {
|
||||
return sdm.UserScore.GetUserScore(ctx, sdm.SendMsgReq.Uid)
|
||||
})
|
||||
|
||||
//获取房管信息
|
||||
g.Go(func() error {
|
||||
return sdm.UserInfo.IsRoomAdmin(ctx, sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid)
|
||||
})
|
||||
|
||||
return g.Wait()
|
||||
}
|
||||
|
||||
//GetRoomConf 获取房间,大航海,房管信息
|
||||
func getRoomConf(ctx context.Context, sdm *SendMsg) error {
|
||||
if err := sdm.RoomConf.Get(ctx, sdm.SendMsgReq.Roomid); err != nil {
|
||||
return err
|
||||
}
|
||||
//获取大航海信息
|
||||
ruid := sdm.RoomConf.UID
|
||||
return sdm.UserInfo.GetPrivilegeType(ctx, sdm.SendMsgReq.Uid, ruid)
|
||||
}
|
135
app/service/live/live-dm/service/v1/getCheckInfo_test.go
Normal file
135
app/service/live/live-dm/service/v1/getCheckInfo_test.go
Normal file
@ -0,0 +1,135 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
v1pb "go-common/app/service/live/live-dm/api/grpc/v1"
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
"go-common/app/service/live/live-dm/dao"
|
||||
"testing"
|
||||
)
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -race -run TestGetCheckMsg
|
||||
func TestGetCheckMsg(t *testing.T) {
|
||||
s := &SendMsg{
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Uid: 111,
|
||||
Roomid: 5392,
|
||||
Ip: "115.239.211.112",
|
||||
Msg: "6666",
|
||||
Rnd: "1000",
|
||||
Fontsize: 15,
|
||||
Mode: 1,
|
||||
Platform: "ios",
|
||||
Msgtype: 0,
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
UserInfo: &dao.UserInfo{
|
||||
MedalInfo: &dao.FansMedalInfo{},
|
||||
},
|
||||
RoomConf: &dao.RoomConf{},
|
||||
UserBindInfo: &dao.UserBindInfo{},
|
||||
TitleConf: &dao.CommentTitle{},
|
||||
DMconf: &dao.DMConf{},
|
||||
UserScore: &dao.UserScore{},
|
||||
}
|
||||
if err := getCheckMsg(context.TODO(), s); err != nil {
|
||||
t.Error("获取检查配置失败:", err)
|
||||
}
|
||||
j, _ := json.Marshal(s)
|
||||
fmt.Print("####", string(j))
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -race -run TestGetRoomConf
|
||||
func TestGetRoomConf(t *testing.T) {
|
||||
var s = &SendMsg{
|
||||
UserInfo: &dao.UserInfo{
|
||||
UserLever: 1,
|
||||
},
|
||||
UserBindInfo: &dao.UserBindInfo{
|
||||
Identification: 0,
|
||||
MobileVerify: 0,
|
||||
},
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Uid: 1877309,
|
||||
Roomid: 5392,
|
||||
Ip: "115.239.211.112",
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
RoomConf: &dao.RoomConf{
|
||||
UID: 158807,
|
||||
},
|
||||
}
|
||||
if err := getRoomConf(context.TODO(), s); err != nil {
|
||||
t.Error("房间配置获取失败")
|
||||
}
|
||||
fmt.Printf("######%+v", s)
|
||||
fmt.Printf("######%+v", s.UserInfo)
|
||||
fmt.Printf("######%+v", s.RoomConf)
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestGetPrivilegeType
|
||||
func TestGetPrivilegeType(t *testing.T) {
|
||||
var s = &SendMsg{
|
||||
UserInfo: &dao.UserInfo{
|
||||
UserLever: 1,
|
||||
},
|
||||
UserBindInfo: &dao.UserBindInfo{
|
||||
Identification: 0,
|
||||
MobileVerify: 0,
|
||||
},
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Uid: 1877309,
|
||||
Roomid: 5392,
|
||||
Ip: "115.239.211.112",
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
RoomConf: &dao.RoomConf{
|
||||
UID: 158807,
|
||||
},
|
||||
}
|
||||
if err := s.UserInfo.GetPrivilegeType(context.TODO(), 1877309, 999); err != nil {
|
||||
t.Error("大航海获取失败")
|
||||
}
|
||||
fmt.Printf("######%d", s.UserInfo.PrivilegeType)
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestIsRoomAdim111
|
||||
func TestIsRoomAdim111(t *testing.T) {
|
||||
var s = &SendMsg{
|
||||
UserInfo: &dao.UserInfo{
|
||||
UserLever: 1,
|
||||
},
|
||||
UserBindInfo: &dao.UserBindInfo{
|
||||
Identification: 0,
|
||||
MobileVerify: 0,
|
||||
},
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Uid: 1877309,
|
||||
Roomid: 5392,
|
||||
Ip: "115.239.211.112",
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
RoomConf: &dao.RoomConf{
|
||||
UID: 158807,
|
||||
},
|
||||
}
|
||||
s.UserInfo.IsRoomAdmin(context.TODO(), 110000654, 460874)
|
||||
if !s.UserInfo.RoomAdmin {
|
||||
t.Error("房管判断失败")
|
||||
}
|
||||
|
||||
s.UserInfo.IsRoomAdmin(context.TODO(), 110000655, 460874)
|
||||
if s.UserInfo.RoomAdmin {
|
||||
t.Error("房管判断失败")
|
||||
}
|
||||
}
|
47
app/service/live/live-dm/service/v1/getDMConf.go
Normal file
47
app/service/live/live-dm/service/v1/getDMConf.go
Normal file
@ -0,0 +1,47 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/library/net/metadata"
|
||||
"go-common/library/sync/errgroup"
|
||||
)
|
||||
|
||||
func getDMconfig(ctx context.Context, sdm *SendMsg) error {
|
||||
g, ctxn := errgroup.WithContext(ctx)
|
||||
if md, ok := metadata.FromContext(ctxn); ok {
|
||||
md[metadata.Mid] = sdm.SendMsgReq.Uid
|
||||
}
|
||||
//获取用户的昵称颜色
|
||||
g.Go(func() error {
|
||||
return sdm.UserInfo.GetUnameColor(ctxn, sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid)
|
||||
})
|
||||
//获取特殊勋章
|
||||
g.Go(func() error {
|
||||
return sdm.UserInfo.MedalInfo.GetSpeicalMedal(ctxn, sdm.SendMsgReq.Uid, sdm.RoomConf.UID)
|
||||
})
|
||||
//获取用户等级RANK
|
||||
g.Go(func() error {
|
||||
return sdm.UserInfo.GetUserLevelRank(ctxn, sdm.SendMsgReq.Uid)
|
||||
})
|
||||
//获取用户头衔
|
||||
g.Go(func() error {
|
||||
return sdm.TitleConf.GetCommentTitle(ctxn)
|
||||
})
|
||||
//获取勋章对应主播的昵称
|
||||
if sdm.UserInfo.MedalInfo.RUID != 0 {
|
||||
g.Go(func() error {
|
||||
return sdm.UserInfo.MedalInfo.GetMedalanchorName(ctxn, sdm.UserInfo.MedalInfo.RUID)
|
||||
})
|
||||
//获取勋章对应主播的房间号
|
||||
g.Go(func() error {
|
||||
return sdm.UserInfo.MedalInfo.GetMedalRoomid(ctxn, sdm.UserInfo.MedalInfo.RUID)
|
||||
})
|
||||
}
|
||||
//获取用户气泡
|
||||
g.Go(func() error {
|
||||
return sdm.UserInfo.GetUserBubble(ctxn, sdm.SendMsgReq.Uid, sdm.SendMsgReq.Roomid, sdm.SendMsgReq.Bubble, sdm.UserInfo.PrivilegeType)
|
||||
})
|
||||
return g.Wait()
|
||||
|
||||
}
|
59
app/service/live/live-dm/service/v1/getDMConf_test.go
Normal file
59
app/service/live/live-dm/service/v1/getDMConf_test.go
Normal file
@ -0,0 +1,59 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
v1pb "go-common/app/service/live/live-dm/api/grpc/v1"
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
"go-common/app/service/live/live-dm/dao"
|
||||
"go-common/library/net/metadata"
|
||||
"testing"
|
||||
)
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -race -run TestGetDMconfig
|
||||
func TestGetDMconfig(t *testing.T) {
|
||||
ctx := metadata.NewContext(context.TODO(), metadata.MD{})
|
||||
s := &SendMsg{
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Uid: 520,
|
||||
Roomid: 5392,
|
||||
Ip: "115.239.211.112",
|
||||
Msg: "6666",
|
||||
Rnd: "1000",
|
||||
Fontsize: 15,
|
||||
Mode: 1,
|
||||
Platform: "ios",
|
||||
Msgtype: 0,
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
UserInfo: &dao.UserInfo{
|
||||
MedalInfo: &dao.FansMedalInfo{},
|
||||
},
|
||||
RoomConf: &dao.RoomConf{
|
||||
UID: 158807,
|
||||
RoomID: 5392,
|
||||
Anchor: "沢奇Sawaki",
|
||||
},
|
||||
UserBindInfo: &dao.UserBindInfo{
|
||||
Uname: "Bili_111",
|
||||
URank: 1000,
|
||||
},
|
||||
TitleConf: &dao.CommentTitle{},
|
||||
DMconf: &dao.DMConf{
|
||||
Mode: 6,
|
||||
Color: 5555,
|
||||
Length: 20,
|
||||
},
|
||||
UserScore: &dao.UserScore{
|
||||
UserScore: 90,
|
||||
},
|
||||
}
|
||||
if err := getDMconfig(ctx, s); err != nil {
|
||||
t.Error("获取弹幕配置失败", err)
|
||||
}
|
||||
j, _ := json.Marshal(s)
|
||||
fmt.Print("####", string(j))
|
||||
}
|
30
app/service/live/live-dm/service/v1/limit.go
Normal file
30
app/service/live/live-dm/service/v1/limit.go
Normal file
@ -0,0 +1,30 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go-common/app/service/live/live-dm/dao"
|
||||
"go-common/library/sync/errgroup"
|
||||
)
|
||||
|
||||
func rateLimit(ctx context.Context, dm *SendMsg) error {
|
||||
lc := &dao.LimitCheckInfo{
|
||||
UID: dm.SendMsgReq.Uid,
|
||||
RoomID: dm.SendMsgReq.Roomid,
|
||||
Msg: dm.SendMsgReq.Msg,
|
||||
MsgType: dm.SendMsgReq.Msgtype,
|
||||
Dao: dm.Dmservice.dao,
|
||||
Conf: dm.LimitConf,
|
||||
}
|
||||
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
g.Go(func() error {
|
||||
return lc.LimitPerSec(ctx)
|
||||
})
|
||||
g.Go(func() error {
|
||||
return lc.LimitSameMsg(ctx)
|
||||
})
|
||||
g.Go(func() error {
|
||||
return lc.LimitRoomPerSecond(ctx)
|
||||
})
|
||||
return g.Wait()
|
||||
}
|
9
app/service/live/live-dm/service/v1/limit_test.go
Normal file
9
app/service/live/live-dm/service/v1/limit_test.go
Normal file
@ -0,0 +1,9 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRateLimit(t *testing.T) {
|
||||
|
||||
}
|
238
app/service/live/live-dm/service/v1/send.go
Normal file
238
app/service/live/live-dm/service/v1/send.go
Normal file
@ -0,0 +1,238 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"go-common/app/service/live/live-dm/dao"
|
||||
"go-common/app/service/live/live-dm/model"
|
||||
"go-common/library/log"
|
||||
"go-common/library/sync/errgroup"
|
||||
|
||||
uuid "github.com/satori/go.uuid"
|
||||
)
|
||||
|
||||
//History 存档信息
|
||||
type History struct {
|
||||
Text string `json:"text"`
|
||||
UID int64 `json:"uid"`
|
||||
NickName string `json:"nickname"`
|
||||
UnameColor string `json:"uname_color"`
|
||||
TimeLine string `json:"timeline"`
|
||||
Isadmin int32 `json:"isadmin"`
|
||||
Vip int `json:"vip"`
|
||||
SVip int `json:"svip"`
|
||||
Medal []interface{} `json:"medal"`
|
||||
Title []interface{} `json:"title"` //内容格式待定
|
||||
UserLevel []interface{} `json:"user_level"`
|
||||
Rank int32 `json:"rank"`
|
||||
Teamid int64 `json:"teamid"`
|
||||
RND string `json:"rnd"`
|
||||
UserTitle string `json:"user_title"`
|
||||
GuardLevel int `json:"guard_level"`
|
||||
Bubble int64 `json:"bubble"`
|
||||
}
|
||||
|
||||
//DatatoString 数据处理转换为json
|
||||
func (h *History) DatatoString(s *SendMsg) string {
|
||||
h.Text = s.SendMsgReq.Msg
|
||||
h.NickName = s.UserBindInfo.Uname
|
||||
h.UID = s.SendMsgReq.Uid
|
||||
h.UnameColor = s.UserInfo.UnameColor
|
||||
h.TimeLine = time.Unix(time.Now().Unix(), 0).Format("2006-01-02 15:04:05")
|
||||
if s.UserInfo.RoomAdmin {
|
||||
h.Isadmin = 1
|
||||
} else {
|
||||
h.Isadmin = 0
|
||||
}
|
||||
h.Vip = s.UserInfo.Vip
|
||||
h.SVip = s.UserInfo.Svip
|
||||
h.Rank = s.UserBindInfo.URank
|
||||
h.Teamid = 0
|
||||
h.RND = s.SendMsgReq.Rnd
|
||||
h.UserTitle = s.TitleConf.Title
|
||||
h.GuardLevel = s.UserInfo.PrivilegeType
|
||||
h.Bubble = s.UserInfo.Bubble
|
||||
|
||||
md := make([]interface{}, 0, 6)
|
||||
if s.UserInfo.MedalInfo.MedalName != "" {
|
||||
md = append(md, s.UserInfo.MedalInfo.MedalLevel)
|
||||
md = append(md, s.UserInfo.MedalInfo.MedalName)
|
||||
md = append(md, s.UserInfo.MedalInfo.RUName) //TODO 获取主播get_weared_medal
|
||||
md = append(md, s.UserInfo.MedalInfo.RoomID)
|
||||
md = append(md, s.UserInfo.MedalInfo.MColor)
|
||||
md = append(md, s.UserInfo.MedalInfo.SpecialMedal)
|
||||
}
|
||||
h.Medal = md
|
||||
|
||||
ul := make([]interface{}, 0, 4)
|
||||
ul = append(ul, s.UserInfo.UserLever)
|
||||
ul = append(ul, 0)
|
||||
ul = append(ul, s.UserInfo.ULevelColor)
|
||||
if s.UserInfo.ULevelRank > 50000 {
|
||||
ul = append(ul, ">50000")
|
||||
} else {
|
||||
ul = append(ul, s.UserInfo.ULevelRank)
|
||||
}
|
||||
h.UserLevel = ul
|
||||
|
||||
tl := make([]interface{}, 0, 2)
|
||||
tl = append(tl, s.TitleConf.OldTitle)
|
||||
tl = append(tl, s.TitleConf.Title)
|
||||
h.Title = tl
|
||||
|
||||
msg, _ := json.Marshal(h)
|
||||
return string(msg)
|
||||
}
|
||||
|
||||
//BroadCastMsg 广播信息
|
||||
type BroadCastMsg struct {
|
||||
CMD string `json:"cmd"`
|
||||
Info []interface{} `json:"info"`
|
||||
}
|
||||
|
||||
//DatatoString 数据处理转换为json
|
||||
func (b *BroadCastMsg) DatatoString(s *SendMsg) string {
|
||||
b.CMD = "DANMU_MSG"
|
||||
b.Info = make([]interface{}, 0, 10)
|
||||
|
||||
//弹幕配置
|
||||
dc := make([]interface{}, 0, 11)
|
||||
dc = append(dc, 0)
|
||||
dc = append(dc, s.SendMsgReq.Mode)
|
||||
dc = append(dc, s.SendMsgReq.Fontsize)
|
||||
dc = append(dc, s.DMconf.Color)
|
||||
dc = append(dc, time.Now().Unix())
|
||||
var rand int64
|
||||
rand, _ = strconv.ParseInt(s.SendMsgReq.Rnd, 10, 64)
|
||||
dc = append(dc, rand)
|
||||
dc = append(dc, 0)
|
||||
dc = append(dc, fmt.Sprintf("%08x", crc32.ChecksumIEEE([]byte(strconv.FormatInt(s.SendMsgReq.Uid, 10)))))
|
||||
dc = append(dc, 0)
|
||||
dc = append(dc, s.SendMsgReq.Msgtype)
|
||||
dc = append(dc, s.UserInfo.Bubble)
|
||||
|
||||
//用户信息
|
||||
userInfo := make([]interface{}, 0, 8)
|
||||
userInfo = append(userInfo, s.SendMsgReq.Uid)
|
||||
userInfo = append(userInfo, s.UserBindInfo.Uname)
|
||||
var admin int
|
||||
if s.UserInfo.RoomAdmin {
|
||||
admin = 1
|
||||
} else {
|
||||
admin = 0
|
||||
}
|
||||
userInfo = append(userInfo, admin)
|
||||
userInfo = append(userInfo, s.UserInfo.Vip)
|
||||
userInfo = append(userInfo, s.UserInfo.Svip)
|
||||
userInfo = append(userInfo, s.UserBindInfo.URank)
|
||||
userInfo = append(userInfo, s.UserBindInfo.MobileVerify)
|
||||
userInfo = append(userInfo, s.UserInfo.UnameColor)
|
||||
|
||||
//勋章配置
|
||||
medalInfo := make([]interface{}, 0, 6)
|
||||
if s.UserInfo.MedalInfo.MedalName != "" {
|
||||
medalInfo = append(medalInfo, s.UserInfo.MedalInfo.MedalLevel)
|
||||
medalInfo = append(medalInfo, s.UserInfo.MedalInfo.MedalName)
|
||||
medalInfo = append(medalInfo, s.UserInfo.MedalInfo.RUName) // 主播名称
|
||||
medalInfo = append(medalInfo, s.UserInfo.MedalInfo.RoomID)
|
||||
medalInfo = append(medalInfo, s.UserInfo.MedalInfo.MColor)
|
||||
medalInfo = append(medalInfo, s.UserInfo.MedalInfo.SpecialMedal)
|
||||
}
|
||||
|
||||
//用户等级信息
|
||||
ul := make([]interface{}, 0, 4)
|
||||
ul = append(ul, s.UserInfo.UserLever)
|
||||
ul = append(ul, 0)
|
||||
ul = append(ul, s.UserInfo.ULevelColor)
|
||||
if s.UserInfo.ULevelRank > 50000 {
|
||||
ul = append(ul, ">50000")
|
||||
} else {
|
||||
ul = append(ul, s.UserInfo.ULevelRank)
|
||||
}
|
||||
|
||||
//头衔
|
||||
tl := make([]interface{}, 0, 2)
|
||||
tl = append(tl, s.TitleConf.OldTitle)
|
||||
tl = append(tl, s.TitleConf.Title)
|
||||
|
||||
//组合
|
||||
b.Info = append(b.Info, dc)
|
||||
b.Info = append(b.Info, s.SendMsgReq.Msg)
|
||||
b.Info = append(b.Info, userInfo)
|
||||
b.Info = append(b.Info, medalInfo)
|
||||
b.Info = append(b.Info, ul)
|
||||
b.Info = append(b.Info, tl)
|
||||
b.Info = append(b.Info, 0)
|
||||
b.Info = append(b.Info, s.UserInfo.PrivilegeType)
|
||||
|
||||
b.Info = append(b.Info, nil)
|
||||
|
||||
msg, _ := json.Marshal(b)
|
||||
return string(msg)
|
||||
}
|
||||
|
||||
func send(ctx context.Context, sdm *SendMsg) error {
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
g.Go(func() error {
|
||||
saveHistory(ctx, sdm)
|
||||
return nil
|
||||
})
|
||||
g.Go(func() error {
|
||||
incrDMNum(ctx, sdm)
|
||||
return nil
|
||||
})
|
||||
g.Go(func() error {
|
||||
return sendBroadCast(ctx, sdm)
|
||||
})
|
||||
//databus投递
|
||||
err := sdm.Dmservice.dao.Databus.Do(context.Background(), func(c context.Context) {
|
||||
sendDataBus(context.Background(), sdm)
|
||||
})
|
||||
if err != nil {
|
||||
log.Error("DM: send databus save err: %+v", err)
|
||||
}
|
||||
return g.Wait()
|
||||
}
|
||||
|
||||
func saveHistory(ctx context.Context, sdm *SendMsg) {
|
||||
hm := &History{}
|
||||
jhm := hm.DatatoString(sdm)
|
||||
sdm.Dmservice.dao.SaveHistory(ctx, jhm, sdm.UserInfo.RoomAdmin, sdm.SendMsgReq.Roomid)
|
||||
}
|
||||
|
||||
func incrDMNum(ctx context.Context, sdm *SendMsg) {
|
||||
dao.IncrDMNum(ctx, sdm.SendMsgReq.Roomid, sdm.SendMsgReq.Msgtype)
|
||||
}
|
||||
|
||||
func sendBroadCast(ctx context.Context, sdm *SendMsg) error {
|
||||
bm := &BroadCastMsg{}
|
||||
jbm := bm.DatatoString(sdm)
|
||||
if err := dao.SendBroadCastGrpc(ctx, jbm, sdm.SendMsgReq.Roomid); err != nil {
|
||||
// if err := dao.SendBroadCast(ctx, jbm, sdm.SendMsgReq.Roomid); err != nil {
|
||||
lancer(sdm, "弹幕投递消息失败")
|
||||
return nil
|
||||
// }
|
||||
// return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func sendDataBus(ctx context.Context, sdm *SendMsg) {
|
||||
info := &model.BNDatabus{
|
||||
Roomid: sdm.SendMsgReq.Roomid,
|
||||
UID: sdm.SendMsgReq.Uid,
|
||||
Uname: sdm.UserBindInfo.Uname,
|
||||
UserLever: sdm.UserInfo.UserLever,
|
||||
Color: sdm.DMconf.Color,
|
||||
Msg: sdm.SendMsgReq.Msg,
|
||||
Time: time.Now().Unix(),
|
||||
MsgType: sdm.SendMsgReq.Msgtype,
|
||||
MsgID: uuid.NewV4().String(),
|
||||
}
|
||||
dao.SendBNDatabus(ctx, sdm.SendMsgReq.Uid, info)
|
||||
}
|
144
app/service/live/live-dm/service/v1/send_test.go
Normal file
144
app/service/live/live-dm/service/v1/send_test.go
Normal file
@ -0,0 +1,144 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
v1pb "go-common/app/service/live/live-dm/api/grpc/v1"
|
||||
"go-common/app/service/live/live-dm/conf"
|
||||
"go-common/app/service/live/live-dm/dao"
|
||||
"testing"
|
||||
)
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestSaveHistory
|
||||
func TestSaveHistory(t *testing.T) {
|
||||
s := &SendMsg{
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Uid: 1877309,
|
||||
Roomid: 5392,
|
||||
Ip: "115.239.211.112",
|
||||
Msg: "66666",
|
||||
Rnd: "1000",
|
||||
Fontsize: 15,
|
||||
Mode: 0,
|
||||
Platform: "ios",
|
||||
Msgtype: 0,
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
dao: dao.New(conf.Conf),
|
||||
},
|
||||
UserInfo: &dao.UserInfo{
|
||||
ULevelColor: 9868950,
|
||||
ULevelRank: 2,
|
||||
MedalInfo: &dao.FansMedalInfo{},
|
||||
RoomAdmin: false,
|
||||
},
|
||||
RoomConf: &dao.RoomConf{
|
||||
UID: 158807,
|
||||
RoomID: 5392,
|
||||
Anchor: "沢奇Sawaki",
|
||||
},
|
||||
UserBindInfo: &dao.UserBindInfo{
|
||||
Uname: "Bili_111",
|
||||
URank: 1000,
|
||||
},
|
||||
TitleConf: &dao.CommentTitle{},
|
||||
DMconf: &dao.DMConf{
|
||||
Mode: 6,
|
||||
Color: 5555,
|
||||
Length: 20,
|
||||
},
|
||||
UserScore: &dao.UserScore{
|
||||
UserScore: 90,
|
||||
},
|
||||
}
|
||||
|
||||
saveHistory(context.TODO(), s)
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestIncrDMNum
|
||||
func TestIncrDMNum(t *testing.T) {
|
||||
s := &SendMsg{
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Uid: 1877309,
|
||||
Roomid: 5392,
|
||||
Ip: "115.239.211.112",
|
||||
Msg: "6666",
|
||||
Rnd: "1000",
|
||||
Fontsize: 15,
|
||||
Mode: 1,
|
||||
Platform: "ios",
|
||||
Msgtype: 0,
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
UserInfo: &dao.UserInfo{
|
||||
ULevelColor: 9868950,
|
||||
ULevelRank: 2,
|
||||
MedalInfo: &dao.FansMedalInfo{},
|
||||
},
|
||||
RoomConf: &dao.RoomConf{
|
||||
UID: 158807,
|
||||
RoomID: 5392,
|
||||
Anchor: "沢奇Sawaki",
|
||||
},
|
||||
UserBindInfo: &dao.UserBindInfo{
|
||||
Uname: "Bili_111",
|
||||
URank: 1000,
|
||||
},
|
||||
TitleConf: &dao.CommentTitle{},
|
||||
DMconf: &dao.DMConf{
|
||||
Mode: 6,
|
||||
Color: 5555,
|
||||
Length: 20,
|
||||
},
|
||||
UserScore: &dao.UserScore{
|
||||
UserScore: 90,
|
||||
},
|
||||
}
|
||||
incrDMNum(context.TODO(), s)
|
||||
}
|
||||
|
||||
//group=qa01 DEPLOY_ENV=uat go test -run TestSendBroadCast
|
||||
func TestSendBroadCast(t *testing.T) {
|
||||
s := &SendMsg{
|
||||
SendMsgReq: &v1pb.SendMsgReq{
|
||||
Uid: 1877309,
|
||||
Roomid: 5392,
|
||||
Ip: "115.239.211.112",
|
||||
Msg: "6666",
|
||||
Rnd: "1000",
|
||||
Fontsize: 15,
|
||||
Mode: 1,
|
||||
Platform: "ios",
|
||||
Msgtype: 0,
|
||||
},
|
||||
Dmservice: &DMService{
|
||||
conf: conf.Conf,
|
||||
},
|
||||
UserInfo: &dao.UserInfo{
|
||||
ULevelColor: 9868950,
|
||||
ULevelRank: 2,
|
||||
MedalInfo: &dao.FansMedalInfo{},
|
||||
},
|
||||
RoomConf: &dao.RoomConf{
|
||||
UID: 158807,
|
||||
RoomID: 5392,
|
||||
Anchor: "沢奇Sawaki",
|
||||
},
|
||||
UserBindInfo: &dao.UserBindInfo{
|
||||
Uname: "Bili_111",
|
||||
URank: 1000,
|
||||
},
|
||||
TitleConf: &dao.CommentTitle{},
|
||||
DMconf: &dao.DMConf{
|
||||
Mode: 6,
|
||||
Color: 5555,
|
||||
Length: 20,
|
||||
},
|
||||
UserScore: &dao.UserScore{
|
||||
UserScore: 90,
|
||||
},
|
||||
}
|
||||
sendBroadCast(context.TODO(), s)
|
||||
}
|
Reference in New Issue
Block a user