Commit 000fd187 authored by hujiebin's avatar hujiebin

init

parents
Pipeline #1912 failed with stages
MODE=local
.idea
/protocol/userProxy/
/protocol/userCenter/
/protocol/biz/
proto:
protoc --go_out=./ --go-grpc_out=. ./protocol/*.proto
\ No newline at end of file
package common
import (
"encoding/binary"
"errors"
"fmt"
"hash/crc32"
"time"
)
const (
MsgTypeLogin = 1 + iota
MsgTypeLoginRsp
MsgTypeHeartBeat
MsgTypeHeartBeatRsp
MsgTypeKickUser
MsgTypeBiz = 7
MsgTypeBizRsp
)
const (
MsgTypeMatchSuccess = 100 + iota
MsgTypeMatchConfirm
MsgTypeCallReady
MsgTypeAddTimeGift
MsgTypeAddTimeFree
)
const (
MsgTypeRecallWindow = 109
MsgTypeVideo = 110 // 1v1视频-v1-黄钻
MsgTypeVideoCallReady = 111
MsgTypeLikeEach = 112
MsgTypeLikeMe = 113
MsgTypeDailyInAppDiamond = 114
MsgTypeGlobalGiftBanner = 115 // 礼物横幅
MsgTypeGlobalGiftBannerRsp = 116
MsgTypeLuckyWheel = 117 //已丢弃
MsgTypeLuckyWheelBanner = 118
MsgTypeDiamondChange = 119 // Kludge:事实上是通用的钻石变更通知了
MsgTypeConfigChange = 120 // 配置变更通知
MsgTypeGlobalRocketNotice = 121 // 火箭全局横幅
MsgTypeGroupChatNotice = 122 // 群发消息弹窗
MsgTypeGlobalBroadcast = 123 // 群发消息弹窗
MsgMicTaskFinish = 124 // 麦上任务完成
MsgFruitMachine = 125 // 水果机开奖
MsgTypeNobleChange = 126 // 贵族变更
MsgTypeJoinGroup = 127 // 加入群组成功
MsgTypeVideoTimeMinuteSuccess = 128 // 1对1视频加时成功
MsgTypeVideoTimeMinuteCheck = 129 // 1对1视频加时检查
MsgTypeVideoMiss = 130 // 1对1视频错过
MsgTypeRoomGroupActivity = 131 // 进房,群组活动推送
MsgTypeVideoV2 = 132 // 1v1视频-v2-粉钻
MsgTypeVideoV2TimeMinuteCheck = 133 // 1v1视频-v2-加时检查
MsgTypeVideoV2CallReady = 134 // 1v1视频-v2-callReady
MsgTypeVideoV2TimeMinuteSuccess = 135 // 1v1视频-v2-加时成功
MsgTypeMatchV2Success = 140 // 匹配-v2-成功
MsgTypeMatchV2Confirm = 141 // 匹配-v2-确认
MsgTypeMatchV2CallReady = 142 // 匹配-v2-callReady
MsgTypeMatchV2AddTimeGift = 143 // 匹配-v2-送礼加时长
)
const (
RoomBannerChange = 1 // 房间banner变更
GiftConfigChange = 2 // 礼物配置变更
OpenScreenChange = 3 // 开屏配置变更
MatchConfigChange = 4 // 匹配配置发生了变化
)
func EncodeMessage(msgType uint32, serialNum uint64, userdata []byte) []byte {
msg := make([]byte, 26)
dataLen := len(userdata)
binary.BigEndian.PutUint16(msg, 1)
binary.BigEndian.PutUint32(msg[2:], msgType)
binary.BigEndian.PutUint64(msg[6:], serialNum)
binary.BigEndian.PutUint64(msg[14:], uint64(time.Now().UnixNano()/1000))
binary.BigEndian.PutUint32(msg[22:], uint32(dataLen))
msg = append(msg, userdata...)
checkSum := crc32.ChecksumIEEE(msg)
msg = append(msg, 0, 0, 0, 0)
binary.BigEndian.PutUint32(msg[26+dataLen:], checkSum)
return msg
}
func DecodeMessage(message []byte) (uint32, uint64, uint64, []byte, error) {
length := len(message)
// 保证消息至少有26bytes
if length >= 26 {
//version := binary.BigEndian.Uint16(message[0:2])
msgType := binary.BigEndian.Uint32(message[2:6])
msgId := binary.BigEndian.Uint64(message[6:14])
timeStamp := binary.BigEndian.Uint64(message[14:22])
dataLen := binary.BigEndian.Uint32(message[22:26])
//log.Printf("DecodeMessage version = %d, msgType = %d, msgId = %d, timeStamp = %d, dataLen = %d\n", version, msgType, msgId, timeStamp, dataLen)
// 保证ws消息至少有msgLen长
if uint32(length) >= dataLen+30 {
pbData := message[26 : dataLen+26]
checksum := binary.BigEndian.Uint32(message[dataLen+26 : dataLen+30])
//fmt.Printf("pbData size = %d, checksum = %d\n", len(pbData), checksum)
myCheckSum := crc32.ChecksumIEEE(message[0 : dataLen+26])
if checksum != myCheckSum {
return 0, msgId, timeStamp, nil, errors.New("checksum error")
}
return msgType, msgId, timeStamp, pbData, nil
} else {
fmt.Printf("payload too short length = %d, msgType = %d\n", length, msgType)
return 0, msgId, timeStamp, nil, errors.New("payload too short")
}
} else {
fmt.Printf("message too short for header %d\n ", length)
return 0, 0, 0, nil, errors.New("message too short")
}
}
package config
import (
"github.com/joho/godotenv"
"github.com/sirupsen/logrus"
"gopkg.in/ini.v1"
"os"
"runtime"
"strconv"
)
//数据库的配置
type MysqlConfig struct {
MYSQL_HOST string
MYSQL_USERNAME string
MYSQL_PASSWORD string
MYSQL_DB string
}
type MysqlCodeConfig struct {
MYSQL_HOST string
MYSQL_USERNAME string
MYSQL_PASSWORD string
MYSQL_DB string
}
//redis配置
type RedisConfig struct {
REDIS_HOST string
REDIS_PASSWORD string
}
//jwt
type JwtConfig struct {
SECRET string
ISSUER_API string
ISSUER_MGR string
EXPIRE string
}
//oss
type OssConfig struct {
OSS_ACCESS_KEY_ID string
OSS_ACCESS_KEY_SECRET string
OSS_ROLE_ARN string
OSS_END_POINT string
OSS_BUCKET string
OSS_CDN string
OSS_EXPIRED_TIME uint
OSS_STS_POINT string
OSS_STS string
OSS_STS_AES string
}
// aws
type AwsConfig struct {
AWS_BUCKET string
AWS_CDN string
AWS_DIR string
CONFIDENCE float32
}
//APP
type AppConfig struct {
BIZ_SECRET string
WEB_SECRET string
OPERATION_SECRET string
SUPERUSER string
OFFICIAL_GROUP string
MINIMAL_VERSION_ANDROID int
MINIMAL_VERSION_IOS int
MODERATE string
}
//googlePay 配置信息
type GooglePayConfig struct {
JsonKey []byte
}
//融云
type RongyunConfig struct {
RONG_CLOUD_APP_KEY string
RONG_CLOUD_APP_SECRET string
RONG_CLOUD_URL string
}
//腾讯云
type TencentyunConfig struct {
TENCENTYUN_APP_ID int
TENCENTYUN_KEY string
TX_OVERSEA_APP_ID int
TX_OVERSEA_KEY string
}
//emas
type EmasConfig struct {
ANDROID_APP_KEY string
ANDROID_APP_SECRET string
REGION_ID string
ACCESS_KEY_ID string
ACCESS_KEY_SECRET string
IOS_APP_KEY string
IOS_APP_SECRET string
APNS string
}
//声网
type AgoraConfig struct {
APP_ID string
APP_CERTIFICATE string
CUSTOMER_KEY string
CUSTOMER_SECRET string
}
//匹配的配置
type MatchConfig struct {
//一开始匹配的默认时长(单位:秒)
MATCH_FREE_TIME int
//一开始匹配的默认时长(单位:秒)VIP
MATCH_FREE_TIME_VIP int
//免费加时的时长 (单位:秒)
MATCH_ADD_TIME_FREE int
//匹配的声网的延迟加时(单位:秒)
MATCH_AGORA_TIME int
//匹配周期(单位:秒)
MATCH_CYCLE int
//过期时间(单位:秒),用户redisCache时间
MATCH_USER_EXPIRES int
//pb match_success中, wait_duration 开始/下一个时间(单位:秒)
MATCH_SUCCESS_WAIT_DURATION uint32
//pb match_success中, single_wait_time_in_sec 单方等待连接最长时间(单位:秒)
MATCH_SUCCESS_SINGLE_WAIT_TIME_IN_SEC uint32
//pb match_success中, dual_wait_time_in_sec 双方连接中最长时间(单位:秒)
MATCH_SUCCESS_DUAL_WAIT_TIME_IN_SEC uint32
}
//在线
type OnlineConfig struct {
//在线周期
ONLINE_CYCLE int
//在线过期时间
ONLINE_USER_EXPIRES int
}
//1对1视频
type VideoConfig struct {
VIDEO_DAILY_FREE_NUM int
//一开始匹配的默认时长(单位:秒)
VIDEO_FREE_TIME int
//一开始匹配的默认时长(单位:秒),vip
VIDEO_FREE_TIME_VIP int
//免费加时的时长 (单位:秒)
VIDEO_ADD_TIME_FREE int
//声网的延迟加时(单位:秒)
VIDEO_AGORA_TIME int
//1分钟视频,普通用户价格
VIDEO_MINUTE_NORMAL int
//1分钟视频,公会用户价格
VIDEO_MINUTE_UNION int
}
//会话
type SessionConfig struct {
SESSION_DAILY_FREE_NUM int
GUILD_USER_HELLO_DAY int
}
type BeanConfig struct {
DIAMOND_BEAN_RATE int
}
type H5Config struct {
USER_LEVEL string
GROUP_SUPPORT string
LUCKY_WHEEL string
WEEKLY_STAR string
WEEKLY_CP string
COUNTRY_STAR string
NOBLE_BUY_IOS string
NOBLE_BUY_IOS_AUDIT string
GUILD_DATA_URL string
MGR_GUILD_DATA_URL string
RANKING_PINK_DIAMOND_URL string
GROUP_POWER_GRADE_URL string
GROUP_POWER_ACT_URL string
SHEEP_H5_URL string
}
type GroupImConfig struct {
MSG_SORT_EXPIRE int
MSG_SORT_SNAP int
MSG_PARALLEL_SIZE int
}
type GradeConfig struct {
//魅力速度
CHARM_SPEED_VIP int
//活跃
ACTITY_SPEED_VIP int
//财富
WEALTH_SPEED_VIP int
}
type LikeConfig struct {
//喜欢人数
I_LIKE_NUM int
//喜欢人数VIP
I_LIKE_NUM_VIP int
//喜欢人数贵族
I_LIKE_NUM_NOBLE int
}
type ApplePayConfig struct {
PASSWORD string
}
type RegisterConfig struct {
IMEI_TOTAL int
IMEI_OAUTH int
ACCOUNT_IP int
ACCOUNT_IP_DURATION int
}
type BannerConfig struct {
GIFT_BANNER_LEVEL1 int
GIFT_BANNER_LEVEL2 int
GIFT_BANNER_LEVEL3 int
}
type DiamondConfig struct {
DAILY_LOGIN_IMEI_LIMIT int
DAILY_LOGIN_IP_LIMIT int
PRIVATE_GIFT_RETURN int
NEW_USER_INVITE_AWARD uint32
}
type LuckWheelConfig struct {
MINIMAL_PARTICIPANT int // 轮盘开始最少需要的参与人数
WAIT_TIMELONG int // 等待轮盘开始的时长(分钟)
WINNER_DIAMOND_BANNER int //全服广播钻石门槛
}
//自定义主题
type GroupCustomThemeConfig struct {
PIC_LIMIT int //图片数量
DAY int //有效天数
}
type GiftConfig struct {
WALL_DIAMOND int //上礼物墙,礼物钻石金额
}
type DailyConfig struct {
LOGIN_COMMON int
LOGIN_VIP int
}
type FruitTycoonConfig struct {
BIG_WINNER_THRESDHOLD uint
BIG_WINNER_LOW uint
BIG_WINNER_HIGH uint
POOL_RATIO uint32
WATERMELON_RATIO uint32
}
type ActivityConfig struct {
COUNTRY_STAR_POOL_RATIO uint32
COUNTRY_STAR_ORDINARY_RATIO uint32
}
type CheckoutConfig struct {
URL string
AUTHORIZATION string
H5 string
HILO_SECRET_KEY string
}
type RiskControlConfig struct {
USER_QPS_LIMIT int64
USER_URL_QPS_LIMIT int64
}
type PayerMaxConfig struct {
URL string
KEY string
MERCHANT_ID string
BIZ_TYPE string
VERSION string
FRONT_CALLBACK_URL string
SHOW_RESULT string
EXPIRE_TIME string
LANGUAGE string
}
type PaypalConfig struct {
PAYPAL_CLIENT_ID string
PAYPAL_SECRET_ID string
RETURN_URL string
}
const (
LOCAL string = "local"
DEBUG string = "debug"
RELEASE string = "release"
)
var mysqlConfigData MysqlConfig
var mysqlCodeConfigData MysqlCodeConfig
var redisConfigData RedisConfig
var jwtConfigData JwtConfig
var appConfigData AppConfig
var ossConfigData OssConfig
var awsConfigData AwsConfig
var googlePayData GooglePayConfig
var rongyunData RongyunConfig
var tencentyunData TencentyunConfig
var emasData EmasConfig
var agora AgoraConfig
var matchData MatchConfig
var onlineData OnlineConfig
var sessionData SessionConfig
var videoData VideoConfig
var beanData BeanConfig
var h5Data H5Config
var groupImData GroupImConfig
var gradeData GradeConfig
var likeData LikeConfig
var applePayData ApplePayConfig
var registerData RegisterConfig
var bannerConfig BannerConfig
var diamondConfig DiamondConfig
var luckyWheelConfig LuckWheelConfig
var groupCustomThemeConfig GroupCustomThemeConfig
var giftConfig GiftConfig
var dailyConfig DailyConfig
var fruitTycoonConfig FruitTycoonConfig
var activityConfig ActivityConfig
var checkoutConfig CheckoutConfig
var riskControl RiskControlConfig
var payerMaxConfig PayerMaxConfig
var paypalConfig PaypalConfig
var mode string
var master bool
func GetConfigMysql() MysqlConfig {
return mysqlConfigData
}
func GetConfigMysqlCode() MysqlCodeConfig {
return mysqlCodeConfigData
}
func GetConfigRedis() RedisConfig {
return redisConfigData
}
func GetConfigJWT() JwtConfig {
return jwtConfigData
}
func GetConfigApp() AppConfig {
return appConfigData
}
func GetConfigOss() OssConfig {
return ossConfigData
}
func GetConfigAws() AwsConfig {
return awsConfigData
}
func GetConfigGooglePay() GooglePayConfig {
return googlePayData
}
func GetMode() string {
return mode
}
func AppIsRelease() bool {
return GetMode() == RELEASE
}
func AppIsLocal() bool {
return GetMode() == LOCAL
}
func IsMaster() bool {
return master
}
func GetOssCDN() string {
return ossConfigData.OSS_CDN
}
func GetRongyunAppKey() string {
return rongyunData.RONG_CLOUD_APP_KEY
}
func GetRongyunAppSecret() string {
return rongyunData.RONG_CLOUD_APP_SECRET
}
func GetRongyunUrl() string {
return rongyunData.RONG_CLOUD_URL
}
func GetTencentyunAppId() int {
return tencentyunData.TENCENTYUN_APP_ID
}
func GetTencentyunKey() string {
return tencentyunData.TENCENTYUN_KEY
}
func GetTxOverSeaAppId() int {
return tencentyunData.TX_OVERSEA_APP_ID
}
func GetTxOverSeaAppKey() string {
return tencentyunData.TX_OVERSEA_KEY
}
func GetEmasRegionId() string {
return emasData.REGION_ID
}
func GetEmasAccessKeyId() string {
return emasData.ACCESS_KEY_ID
}
func GetEmasAccessKeySecret() string {
return emasData.ACCESS_KEY_SECRET
}
func GetEmasAndroidAppKey() string {
return emasData.ANDROID_APP_KEY
}
func GetEmasIosAppKey() string {
return emasData.IOS_APP_KEY
}
func GetEmasApns() string {
return emasData.APNS
}
func GetAgoraAppId() string {
return agora.APP_ID
}
func GetAgoraAppCertificate() string {
return agora.APP_CERTIFICATE
}
func GetAgoraCustomerKey() string {
return agora.CUSTOMER_KEY
}
func GetAgoraCustomerSecret() string {
return agora.CUSTOMER_SECRET
}
func GetMatchConfig() *MatchConfig {
return &matchData
}
func GetOnlineConfig() *OnlineConfig {
return &onlineData
}
func GetSessionConfig() SessionConfig {
return sessionData
}
func GetVideoConfig() VideoConfig {
return videoData
}
func GetBeanConfig() BeanConfig {
return beanData
}
func GetH5Config() H5Config {
return h5Data
}
func GetGroupImConfig() GroupImConfig {
return groupImData
}
func GetGradeConfig() GradeConfig {
return gradeData
}
func GetLikeConfig() LikeConfig {
return likeData
}
func GetApplePayConfig() ApplePayConfig {
return applePayData
}
func GetRegisterConfig() RegisterConfig {
return registerData
}
func GetBannerConfig() BannerConfig {
return bannerConfig
}
func GetDiamondConfig() DiamondConfig {
return diamondConfig
}
func GetLuckyWheelConfig() LuckWheelConfig {
return luckyWheelConfig
}
func GetGroupCustomThemeConfig() GroupCustomThemeConfig {
return groupCustomThemeConfig
}
func GetGiftConfig() GiftConfig {
return giftConfig
}
func GetDailyConfig() DailyConfig {
return dailyConfig
}
func GetFruitTycoonConfig() FruitTycoonConfig {
return fruitTycoonConfig
}
func GetActivityConfig() ActivityConfig {
return activityConfig
}
func GetCheckoutConfig() CheckoutConfig {
return checkoutConfig
}
func GetRiskControlConfig() RiskControlConfig {
return riskControl
}
func GetPayerMaxConfig() PayerMaxConfig {
return payerMaxConfig
}
func GetPaypalConfig() PaypalConfig {
return paypalConfig
}
func init() {
str, _ := os.Getwd()
logrus.New().Info(str)
envDir := ".env"
//加载环境变量
if err := godotenv.Load(envDir); err != nil {
logrus.New().Fatalf("Error loading .env err:%v", err)
}
//获取环境变量
mode = os.Getenv("MODE")
var err error
master, _ = strconv.ParseBool(os.Getenv("MASTER"))
logrus.New().Infof("My role is %t", master)
iniDir := mode + ".ini"
if runtime.GOOS == "darwin" { // mac本地调试
iniDir = "/var/log/hilo/" + iniDir
}
//根据环境变量获取具体的配置,实现多环境配置
//var conf *ini.File
conf, err := ini.LoadSources(ini.LoadOptions{IgnoreInlineComment: true}, iniDir)
if err != nil {
logrus.New().Fatal(err)
}
//加载mysql的配置
if err := conf.Section("DATABASE").MapTo(&mysqlConfigData); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("DATABASECODE").MapTo(&mysqlCodeConfigData); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("REDIS").MapTo(&redisConfigData); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("JWT").MapTo(&jwtConfigData); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("APP").MapTo(&appConfigData); err != nil {
logrus.New().Fatal(err)
} else {
logrus.New().Infof("APP: %+v", appConfigData)
}
if err := conf.Section("OSS").MapTo(&ossConfigData); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("AWS").MapTo(&awsConfigData); err != nil {
logrus.New().Fatal(err)
} else {
if awsConfigData.CONFIDENCE <= 50 {
awsConfigData.CONFIDENCE = 80
}
logrus.New().Infof("AWS: %+v", awsConfigData)
}
if err := conf.Section("RONGYUN").MapTo(&rongyunData); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("TENCENTYUN").MapTo(&tencentyunData); err != nil {
logrus.New().Fatal(err)
} else {
logrus.New().Info("TENCENTYUN: ", tencentyunData)
}
if err := conf.Section("EMAS").MapTo(&emasData); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("AGORA").MapTo(&agora); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("MATCH").MapTo(&matchData); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("ONLINE").MapTo(&onlineData); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("SESSION").MapTo(&sessionData); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("VIDEO").MapTo(&videoData); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("BEAN").MapTo(&beanData); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("H5").MapTo(&h5Data); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("GROUPIM").MapTo(&groupImData); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("GRADE").MapTo(&gradeData); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("LIKE").MapTo(&likeData); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("APPLEPAY").MapTo(&applePayData); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("REGISTER").MapTo(&registerData); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("BANNER").MapTo(&bannerConfig); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("DIAMOND").MapTo(&diamondConfig); err != nil {
logrus.New().Fatal(err)
} else {
if diamondConfig.NEW_USER_INVITE_AWARD <= 0 {
diamondConfig.NEW_USER_INVITE_AWARD = 5000
}
}
if err := conf.Section("LUCKY_WHEEL").MapTo(&luckyWheelConfig); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("GROUP_CUSTOM_THEME").MapTo(&groupCustomThemeConfig); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("GIFT").MapTo(&giftConfig); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("DAILY").MapTo(&dailyConfig); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("CHECKOUT").MapTo(&checkoutConfig); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("PAYER_MAX").MapTo(&payerMaxConfig); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("PAYPAL").MapTo(&paypalConfig); err != nil {
logrus.New().Fatal(err)
}
if err := conf.Section("FRUIT_TYCOON").MapTo(&fruitTycoonConfig); err != nil {
logrus.New().Fatal(err)
} else {
// 防止未配置或配置错误
if fruitTycoonConfig.BIG_WINNER_LOW <= 0 {
fruitTycoonConfig.BIG_WINNER_LOW = 10000
}
if fruitTycoonConfig.BIG_WINNER_HIGH <= 0 {
fruitTycoonConfig.BIG_WINNER_HIGH = 20000
}
if fruitTycoonConfig.POOL_RATIO <= 0 || fruitTycoonConfig.POOL_RATIO > 100 {
fruitTycoonConfig.POOL_RATIO = 20
}
if fruitTycoonConfig.WATERMELON_RATIO <= 0 || fruitTycoonConfig.WATERMELON_RATIO > 100 {
fruitTycoonConfig.WATERMELON_RATIO = 70
}
logrus.New().Infof("FRUIT_TYCOON: %+v", fruitTycoonConfig)
}
if err := conf.Section("ACTIVITY").MapTo(&activityConfig); err != nil {
logrus.New().Fatal(err)
} else {
// 防止未配置或配置错误
if activityConfig.COUNTRY_STAR_POOL_RATIO <= 0 {
activityConfig.COUNTRY_STAR_POOL_RATIO = 20
}
if activityConfig.COUNTRY_STAR_ORDINARY_RATIO <= 0 {
activityConfig.COUNTRY_STAR_ORDINARY_RATIO = 20
}
logrus.New().Infof("ACTIVITY: %+v", activityConfig)
}
if err := conf.Section("RISK_CONTROL").MapTo(&riskControl); err != nil {
logrus.New().Fatal(err)
} else {
if riskControl.USER_QPS_LIMIT <= 0 {
riskControl.USER_QPS_LIMIT = 128
}
if riskControl.USER_URL_QPS_LIMIT <= 0 {
riskControl.USER_URL_QPS_LIMIT = 64
}
logrus.New().Infof("RISK_CONTROL: %+v", riskControl)
}
}
package consul
import (
"fmt"
"github.com/hashicorp/consul/api"
"math/rand"
"strconv"
)
func GetAgentInfo(client *api.Client) (string, string) {
info, err := client.Agent().Self()
if err != nil {
fmt.Printf("%v\n", err)
return "", ""
}
if info == nil {
fmt.Println("Fail to get consul info.")
return "", ""
}
ip := ""
inter := info["DebugConfig"]["AdvertiseAddrLAN"]
switch inter.(type) {
case string:
ip = inter.(string)
break
}
nodeName := ""
inter = info["Config"]["NodeName"]
switch inter.(type) {
case string:
nodeName = inter.(string)
break
}
return ip, nodeName
}
func SelectService(cataLog *api.Catalog, serviceName string, nodeName string) (string, error) {
services, _, err := cataLog.Service(serviceName, "", nil)
if err != nil {
return "", err
}
if len(services) == 0 {
fmt.Println("userCenter not found in catalog.")
return "", nil
}
var count int32 = 0
addr := ""
for _, s := range services {
fmt.Printf("service info: %v\n", s)
if s.ServiceWeights.Passing == 1 {
count++
if s.Node == nodeName {
addr = s.ServiceAddress + ":" + strconv.Itoa(s.ServicePort)
break
} else {
if rand.Int31n(count) == 0 {
addr = s.ServiceAddress + ":" + strconv.Itoa(s.ServicePort)
}
}
}
}
return addr, nil
}
func GetServices(cataLog *api.Catalog, serviceName string) ([]string, error) {
addrs := make([]string, 0)
services, _, err := cataLog.Service(serviceName, "", nil)
if err == nil {
for _, s := range services {
fmt.Printf("service info: %s, %s, %s:%d", s.ID, s.Node, s.ServiceAddress, s.ServicePort)
if s.ServiceWeights.Passing == 1 {
addrs = append(addrs, s.ServiceAddress+":"+strconv.Itoa(s.ServicePort))
}
}
}
return addrs, nil
}
package dingding
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
var (
ROBOTWEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=5207fd753d28661ea0716ea0ef5b9e9e0aea392c9a148307c0b186e3d09b4aec"
HILO = "hilo:"
)
type dingResponse struct {
Errcode int
Errmsg string
}
type dingtextMessage struct {
MsgType string `json:"msgtype"`
Text dingtextParams `json:"text"`
At dingdingAt `json:"at"`
}
type dingtextParams struct {
Content string `json:"content"`
}
// At at struct
type dingdingAt struct {
AtMobiles []string `json:"atMobiles"`
IsAtAll bool `json:"isAtAll"`
}
func SendDingRobot(url string, content string, isAtAll bool) error {
msg := dingtextMessage{MsgType: "text", Text: dingtextParams{Content: HILO + content}, At: dingdingAt{IsAtAll: isAtAll}}
m, err := json.Marshal(msg)
if err != nil {
return err
}
resp, err := http.Post(url, "application/json", bytes.NewReader(m))
if err != nil {
return err
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
var dr dingResponse
err = json.Unmarshal(data, &dr)
if err != nil {
return err
}
if dr.Errcode != 0 {
return fmt.Errorf("dingrobot send failed: %v", dr.Errmsg)
}
return nil
}
package mylogrus
import (
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
"github.com/rifflock/lfshook"
"github.com/sirupsen/logrus"
"hilo-socketCenter/common/config"
"io"
"os"
"path/filepath"
"time"
)
const logDir = "/var/log/hilo/"
var filenamePrefix string
var MyLog = logrus.New()
func Info(v interface{}) {
MyLog.Info("")
}
func init() {
filenamePrefix = logDir + filepath.Base(os.Args[0]) + "."
//if runtime.GOOS == "darwin" { // mac本地调试
// filenamePrefix = "./log/hilo/" + filepath.Base(os.Args[0]) + "."
//}
// stderr日志重定向
MyLog.SetOutput(os.Stdout)
RewriteStderrFile()
if config.AppIsRelease() {
MyLog.SetFormatter(&logrus.JSONFormatter{
DisableHTMLEscape: true,
TimestampFormat: "2006-01-02 15:04:05.000",
})
hook := lfshook.NewHook(lfshook.WriterMap{
logrus.DebugLevel: getLevelWrite(logrus.DebugLevel),
logrus.InfoLevel: getLevelWrite(logrus.InfoLevel),
logrus.WarnLevel: getLevelWrite(logrus.WarnLevel),
logrus.ErrorLevel: getLevelWrite(logrus.ErrorLevel),
logrus.FatalLevel: getLevelWrite(logrus.FatalLevel),
logrus.PanicLevel: getLevelWrite(logrus.PanicLevel),
}, &logrus.JSONFormatter{DisableHTMLEscape: true, TimestampFormat: time.RFC3339Nano})
MyLog.AddHook(hook)
MyLog.SetLevel(logrus.InfoLevel)
MyLog.SetReportCaller(true)
} else {
MyLog.SetFormatter(&logrus.TextFormatter{
ForceQuote: false,
DisableQuote: true,
TimestampFormat: "2006-01-02 15:04:05.000",
FullTimestamp: true,
})
hook := lfshook.NewHook(lfshook.WriterMap{
logrus.DebugLevel: getLevelWrite(logrus.DebugLevel),
logrus.InfoLevel: getLevelWrite(logrus.InfoLevel),
logrus.WarnLevel: getLevelWrite(logrus.WarnLevel),
logrus.ErrorLevel: getLevelWrite(logrus.ErrorLevel),
logrus.FatalLevel: getLevelWrite(logrus.FatalLevel),
logrus.PanicLevel: getLevelWrite(logrus.PanicLevel),
}, &logrus.TextFormatter{ForceQuote: false, DisableQuote: true, TimestampFormat: time.RFC3339Nano})
MyLog.AddHook(hook)
MyLog.SetLevel(logrus.InfoLevel)
MyLog.SetReportCaller(true)
}
}
func GetInfoLog() io.Writer {
return getLevelWrite(logrus.InfoLevel)
}
func getLevelWrite(level logrus.Level) io.Writer {
var name string
switch level {
case logrus.DebugLevel:
name = "debug.log"
case logrus.InfoLevel:
name = "info.log"
case logrus.WarnLevel:
name = "warn.log"
case logrus.ErrorLevel:
name = "error.log"
case logrus.FatalLevel:
name = "fatal.log"
case logrus.PanicLevel:
name = "panic.log"
}
name = filenamePrefix + name
writer, err := rotatelogs.New(
name+".%Y%m%d%H",
rotatelogs.WithLinkName(name), // 生成软链,指向最新日志文件
rotatelogs.WithMaxAge(7*24*time.Hour), // 文件最大保存时间
rotatelogs.WithRotationTime(time.Hour), // 日志切割时间间隔
)
if err != nil {
MyLog.Fatal("Failed to create log file:", err.Error())
}
return writer
}
func GetSqlLog() io.Writer {
//if !config.AppIsRelease() {
// return GetInfoLog()
//}
//name := filenamePrefix + "sql.log"
//file, err := os.OpenFile(name, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
//if err == nil {
// return file
//} else {
// MyLog.Fatal("Failed to create sql log file:", err.Error())
//}
var name string = "sql.log"
name = filenamePrefix + name
writer, err := rotatelogs.New(
name+".%Y%m%d%H",
rotatelogs.WithLinkName(name), // 生成软链,指向最新日志文件
rotatelogs.WithMaxAge(7*24*time.Hour), // 文件最大保存时间
rotatelogs.WithRotationTime(time.Hour), // 日志切割时间间隔
)
if err != nil {
MyLog.Fatal("Failed to create log file:", err.Error())
}
return writer
}
//go:build !windows
// +build !windows
package mylogrus
import (
"fmt"
"os"
"path/filepath"
"runtime"
"syscall"
"time"
)
var stdErrFileHandler *os.File
func RewriteStderrFile() {
filename := logDir + filepath.Base(os.Args[0]) + ".stderr.log"
//if runtime.GOOS == "darwin" { // mac本地调试
// filename = "./log/hilo/" + filepath.Base(os.Args[0]) + ".stderr.log"
//}
if exits, _ := pathExists(filename); exits {
os.Rename(filename, filename+"_"+time.Now().Format("20060102150405"))
}
file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
fmt.Println(err)
return
}
stdErrFileHandler = file //把文件句柄保存到全局变量,避免被GC回收
if err = syscall.Dup2(int(file.Fd()), int(os.Stderr.Fd())); err != nil {
fmt.Println(err)
return
}
// 内存回收前关闭文件描述符
runtime.SetFinalizer(stdErrFileHandler, func(fd *os.File) {
fd.Close()
})
return
}
func pathExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
//go:build windows
// +build windows
package mylogrus
import (
"os"
"path/filepath"
"time"
)
func RewriteStderrFile() {
filename := logDir + filepath.Base(os.Args[0]) + ".stderr.log"
if exits, _ := pathExists(filename); exits {
os.Rename(filename, filename+"_"+time.Now().Format("20060102150405"))
}
file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
MyLog.Errorf("stderr log in:%v,err:%v", file, err)
}
func pathExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
package mysql
import (
"strconv"
)
/**
基于PDM,建立统计的数据domain结构。注意,不要选择0, 因为go的int默认值为0
*/
//主键ID
type ID = uint64
//性别
type Sex = uint8
//加减
type AddReduce = uint8
//拥有
type YesNo = uint8
//短描述
type Str = string
//时间戳
type Time = int64
//状态
type UserYesNo = uint8
//平台
type Platform = uint8
//多枚举类型
type Type = uint8
//数量
type Num = uint32
//时间戳
type Timestamp = uint64
//排序
type Index = uint16
//数量,并且用到-1作为特殊标记位
type NumAll = int
//开启关闭
type OpenClose = uint8
//逻辑删除
type LogicDel = uint8
//设备
type Device = uint8
type PeriodType = uint8
type FinishYesNo = uint8
type PayOrderType = uint8
//性别
const (
MAN Sex = 1
WOMAN Sex = 2
EMPTY Sex = 0
)
//yes no
const (
YES YesNo = 1
NO YesNo = 2
)
const (
OPEN OpenClose = 1
CLOSE OpenClose = 2
)
//加,减
const (
ADD AddReduce = 1
REDUCE AddReduce = 2
NilAddREDUCE AddReduce = 3
)
const (
USER UserYesNo = 1
NOUSER UserYesNo = 2
)
const (
Apple Platform = 1
GOOGLE Platform = 2
EGG_PLANT Platform = 3 // 通过starchat回调的茄子充值 代理充值
Checkout Platform = 4
PayerMax Platform = 5 // 通过hilo发起,starchat回调的PayerMax/茄子充值
Paypal Platform = 6 // paypal
ApplePink Platform = 31 // Apple pay 购买粉钻
GOOGLEPink Platform = 32 // GOOGLE pay 购买粉钻
PayTypeZero PayOrderType = 0 //
PayTypeProxy PayOrderType = 1 // 1.代理给自己充值
PayTypeUserToProxy PayOrderType = 2 // 2.用户给代理充值
CheckoutName = "cheakout支付"
PayerMaxName = "茄子支付"
PayPalName = "PayPal支付"
)
//逻辑删除
const (
EXIST LogicDel = 1
DEL LogicDel = 2
)
const (
DAY PeriodType = 1
Week PeriodType = 2
Month PeriodType = 3
Year PeriodType = 4
)
const (
FinishNo FinishYesNo = 0
FinishYes FinishYesNo = 1
)
const (
DiamondYellow Type = 1
DiamondPink Type = 2
)
func IdToStr(id ID) string {
return strconv.Itoa(int(id))
}
func StrToId(id string) (ID, error) {
var idInt int
var err error
if idInt, err = strconv.Atoi(id); err != nil {
return 0, err
}
return ID(idInt), nil
}
func NumToString(num Num) string {
return strconv.Itoa(int(num))
}
func TypeToString(t Type) string {
return strconv.Itoa(int(t))
}
func StrToType(t string) (Type, error) {
var tInt int
var err error
if tInt, err = strconv.Atoi(t); err != nil {
return 0, err
}
return Type(tInt), nil
}
/*func IdToUint64(id ID) uint64 {
return uint64(id)
}*/
func IdsToUint64(ids []ID) []uint64 {
uints := []uint64{}
for i := 0; i < len(ids); i++ {
uints = append(uints, uint64(ids[i]))
}
return uints
}
package mysql
import "time"
type EntityI interface {
GetID() ID
//用于判断数据是否进行持久化
IsLazyLoad() bool
//默认值为false true:代表要移除数据
CheckDel() bool
//检查是否唯一键冲突,依旧更新
CheckOnDuplicateKeyUPDATE() bool
//检查是否唯一键冲突,则不插入
CheckOnDuplicateKeyIGNORE() bool
//更新乐观锁 默认值为false true:乐观锁更新
CheckUpdateVersion() bool
//更新条件.
CheckUpdateCondition() bool
//获取版本号
GetUpdateVersionBefore() uint
//更新情况
GetUpdateCondition() string
//save 动作排除字段
GetOmit() []string
}
type Entity struct {
ID ID `gorm:"primary_key"`
CreatedTime time.Time `gorm:"->"`
UpdatedTime time.Time `gorm:"->"`
lazyLoad bool `gorm:"-"`
del bool `gorm:"-"`
onDuplicateKeyUPDATE bool `gorm:"-"`
onDuplicateKeyIGNORE bool `gorm:"-"`
updateVersionFlag bool `gorm:"-"`
updateVersionBefore uint `gorm:"-"`
updateCondition string `gorm:"-"`
omit []string `gorm:"-"` //更新排除
updateColumns map[string]interface{} `gorm:"-"` //更新字段
}
func (t *Entity) GetID() ID {
return t.ID
}
func (t *Entity) IsLazyLoad() bool {
return t.lazyLoad
}
func (t *Entity) SetLasyLoad() {
t.lazyLoad = true
}
func (t *Entity) SetDel() {
t.del = true
}
func (t *Entity) CheckDel() bool {
return t.del
}
func (t *Entity) SetOnDuplicateKeyUPDATE() {
t.onDuplicateKeyUPDATE = true
}
func (t *Entity) SetOnDuplicateKeyIGNORE() {
t.onDuplicateKeyIGNORE = true
}
func (t *Entity) CheckOnDuplicateKeyUPDATE() bool {
return t.onDuplicateKeyUPDATE
}
func (t *Entity) CheckOnDuplicateKeyIGNORE() bool {
return t.onDuplicateKeyIGNORE
}
func (t *Entity) SetCheckUpdateVersionBefore(versionBefore uint) {
t.updateVersionBefore = versionBefore
t.updateVersionFlag = true
}
func (t *Entity) SetCheckUpdateCondition(condition string) {
t.updateCondition = condition
}
func (t *Entity) CheckUpdateVersion() bool {
return t.updateVersionFlag
}
func (t *Entity) CheckUpdateCondition() bool {
return t.updateCondition != ""
}
func (t *Entity) GetUpdateCondition() string {
return t.updateCondition
}
func (t *Entity) GetUpdateVersionBefore() uint {
return t.updateVersionBefore
}
func (t *Entity) GetOmit() []string {
return t.omit
}
func (t *Entity) SetOmit(omit []string) {
t.omit = omit
}
func (t *Entity) SetUpdateColumns(updateColumns map[string]interface{}) {
t.updateColumns = updateColumns
}
func (t *Entity) GetUpdateColumns() map[string]interface{} {
return t.updateColumns
}
package mysql
import (
"context"
"fmt"
. "gorm.io/gorm/logger"
"gorm.io/gorm/utils"
"time"
)
func MyNew(writer Writer, config Config) Interface {
var (
infoStr = "%s[info] "
warnStr = "%s[warn] "
errStr = "%s[error] "
traceStr = "%s[%.3fms] [rows:%v] %s"
traceWarnStr = "%s %s[%.3fms] [rows:%v] %s"
traceErrStr = "%s %s[%.3fms] [rows:%v] %s"
)
//if config.Colorful {
// infoStr = Green + "%s\n" + Reset + Green + "[info] " + Reset
// warnStr = BlueBold + "%s\n" + Reset + Magenta + "[warn] " + Reset
// errStr = Magenta + "%s\n" + Reset + Red + "[error] " + Reset
// traceStr = Green + "%s\n" + Reset + Yellow + "[%.3fms] " + BlueBold + "[rows:%v]" + Reset + " %s"
// traceWarnStr = Green + "%s " + Yellow + "%s\n" + Reset + RedBold + "[%.3fms] " + Yellow + "[rows:%v]" + Magenta + " %s" + Reset
// traceErrStr = RedBold + "%s " + MagentaBold + "%s\n" + Reset + Yellow + "[%.3fms] " + BlueBold + "[rows:%v]" + Reset + " %s"
//}
myTraceStr := " traceId:%v userId:%v"
infoStr += myTraceStr
warnStr += myTraceStr
errStr += myTraceStr
traceStr += myTraceStr
traceWarnStr += myTraceStr
traceErrStr += myTraceStr
return &myLogger{
Writer: writer,
Config: config,
infoStr: infoStr,
warnStr: warnStr,
errStr: errStr,
traceStr: traceStr,
traceWarnStr: traceWarnStr,
traceErrStr: traceErrStr,
}
}
type myLogger struct {
Writer
Config
infoStr, warnStr, errStr string
traceStr, traceErrStr, traceWarnStr string
}
// LogMode log mode
func (l *myLogger) LogMode(level LogLevel) Interface {
newlogger := *l
newlogger.LogLevel = level
return &newlogger
}
// Info print info
func (l myLogger) Info(ctx context.Context, msg string, data ...interface{}) {
if l.LogLevel >= Info {
l.Printf(l.infoStr+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...)
}
}
// Warn print warn messages
func (l myLogger) Warn(ctx context.Context, msg string, data ...interface{}) {
if l.LogLevel >= Warn {
l.Printf(l.warnStr+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...)
}
}
// Error print error messages
func (l myLogger) Error(ctx context.Context, msg string, data ...interface{}) {
if l.LogLevel >= Error {
l.Printf(l.errStr+msg, append([]interface{}{utils.FileWithLineNum()}, data...)...)
}
}
// Trace print sql message
func (l myLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
traceId, userId := ctx.Value("traceId"), ctx.Value("userId")
if l.LogLevel > Silent {
elapsed := time.Since(begin)
switch {
case err != nil && l.LogLevel >= Error:
sql, rows := fc()
if rows == -1 {
l.Printf(l.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, "-", sql, traceId, userId)
} else {
l.Printf(l.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, rows, sql, traceId, userId)
}
case elapsed > l.SlowThreshold && l.SlowThreshold != 0 && l.LogLevel >= Warn:
sql, rows := fc()
slowLog := fmt.Sprintf("SLOW SQL >= %v", l.SlowThreshold)
if rows == -1 {
l.Printf(l.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, "-", sql, traceId, userId)
} else {
l.Printf(l.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, rows, sql, traceId, userId)
}
case l.LogLevel == Info:
sql, rows := fc()
if rows == -1 {
l.Printf(l.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, "-", sql, traceId, userId)
} else {
l.Printf(l.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql, traceId, userId)
}
}
}
}
package mysql
import (
"fmt"
_ "github.com/go-sql-driver/mysql" //加载mysql驱动
_ "github.com/joho/godotenv/autoload"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/gorm/schema"
"hilo-socketCenter/common/config"
"hilo-socketCenter/common/mylogrus"
"log"
"net/url"
"time"
)
var Db *gorm.DB
func init() {
var err error
mysqlConfigData := config.GetConfigMysql()
options := "?charset=utf8mb4&parseTime=True&loc=Local&time_zone=" + url.QueryEscape("'+8:00'")
dsn := "" + mysqlConfigData.MYSQL_USERNAME + ":" + mysqlConfigData.MYSQL_PASSWORD + "@(" + mysqlConfigData.MYSQL_HOST + ")/" + mysqlConfigData.MYSQL_DB + options
sqlLogger := logger.Default.LogMode(logger.Info)
if file := mylogrus.GetSqlLog(); file != nil {
//sqlLogger = logger.New(log.New(file, "\r\n", log.Ldate|log.Lmicroseconds), logger.Config{
sqlLogger = MyNew(log.New(file, "", log.Ldate|log.Lmicroseconds), logger.Config{
SlowThreshold: 200 * time.Millisecond,
LogLevel: logger.Info,
Colorful: false,
})
}
Db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
Logger: sqlLogger,
NamingStrategy: schema.NamingStrategy{
SingularTable: true,
},
})
if err != nil {
log.Fatalf("mysql connect error %v", err)
} else {
log.Println("mysql connect success")
}
if Db.Error != nil {
fmt.Printf("database error %v", Db.Error)
}
if d, err := Db.DB(); err == nil {
d.SetConnMaxLifetime(time.Minute * 30) // 连接可复用的最大时间。
d.SetMaxIdleConns(200) // 空闲连接数
}
//移除entity的tableName
/* gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string {
return strings.Replace(defaultTableName, "_entities", "", 1)
}*/
//Db.Callback().Create().Replace("gorm:update_time_stamp", updateTimeStampForCreateCallback)
//Db.Callback().Update().Replace("gorm:update_time_stamp", updateTimeStampForUpdateCallback)
/* Db.SingularTable(true)
Db.DB().SetMaxIdleConns(10)
Db.DB().SetMaxOpenConns(100)
Db.LogMode(true)
Db.SetLogger(log.New(os.Stdout, "\r\n", 0))*/
}
/*func updateTimeStampForUpdateCallback(scope *gorm.Scope) {
if _, ok := scope.Get("gorm:update_column"); !ok {
_ = scope.SetColumn("UpdatedTime", time.Now().Unix())
}
}
func updateTimeStampForCreateCallback(scope *gorm.Scope) {
if !scope.HasError() {
nowTime := time.Now().Unix()
if createTimeField, ok := scope.FieldByName("CreatedTime"); ok {
if createTimeField.IsBlank {
_ = createTimeField.Set(nowTime)
}
}
if modifyTimeField, ok := scope.FieldByName("UpdatedTime"); ok {
if modifyTimeField.IsBlank {
_ = modifyTimeField.Set(nowTime)
}
}
}
}*/
func HasTable(tableName string) bool {
//var num int
//err := Db.Exec("SELECT COUNT(*) num FROM information_schema.TABLES WHERE table_name =%s;", tableName).Pluck("num", &num).Error
//if err != nil {
// mylogrus.MyLog.Errorf("HasTable err: %v, stack: %v", err, string(debug.Stack()))
// return
//}
//if num > 0 {
// has = true
//}
return Db.Migrator().HasTable(tableName)
}
package redisCli
import (
"context"
"github.com/go-redis/redis/v8"
"hilo-socketCenter/common/config"
"hilo-socketCenter/common/mylogrus"
"log"
)
var RedisClient *redis.Client
var RedisClient1 *redis.Client
func init() {
RedisClient = redis.NewClient(&redis.Options{
Addr: config.GetConfigRedis().REDIS_HOST,
Password: config.GetConfigRedis().REDIS_PASSWORD, // no password set
DB: 0, // use default DB
PoolSize: 2000,
MinIdleConns: 200,
})
mylogrus.MyLog.Infoln(config.GetConfigRedis().REDIS_HOST)
mylogrus.MyLog.Infoln(config.GetConfigRedis().REDIS_PASSWORD)
pong, err := RedisClient.Ping(context.Background()).Result()
if err != nil {
mylogrus.MyLog.Warn(err)
mylogrus.MyLog.Fatal("redis db0 connect fail")
} else {
mylogrus.MyLog.Info("redis db0 connection success - ", pong)
}
RedisClient1 = redis.NewClient(&redis.Options{
Addr: config.GetConfigRedis().REDIS_HOST,
Password: config.GetConfigRedis().REDIS_PASSWORD, // no password set
DB: 1, // use default DB
PoolSize: 200,
MinIdleConns: 20,
})
mylogrus.MyLog.Infoln(config.GetConfigRedis().REDIS_HOST)
mylogrus.MyLog.Infoln(config.GetConfigRedis().REDIS_PASSWORD)
pong, err = RedisClient1.Ping(context.Background()).Result()
if err != nil {
mylogrus.MyLog.Warn(err)
mylogrus.MyLog.Fatal("redis db1 connect fail")
} else {
log.Println("redis db1 connection success - " + pong)
}
// log hook
//RedisClient.AddHook(redisHook{})
}
func GetRedis() *redis.Client {
return RedisClient
}
func GetRedis1() *redis.Client {
return RedisClient1
}
package redisCli
import (
"context"
"github.com/go-redis/redis/v8"
"hilo-socketCenter/common/mylogrus"
"time"
)
type redisCost struct{}
var redisCostKey = redisCost{}
type redisHook struct{}
func (redisHook) BeforeProcess(ctx context.Context, cmd redis.Cmder) (context.Context, error) {
ctx = context.WithValue(ctx, redisCostKey, time.Now())
return ctx, nil
}
func (redisHook) AfterProcess(ctx context.Context, cmd redis.Cmder) error {
traceId, userId := ctx.Value("traceId"), ctx.Value("userId")
start := ctx.Value(redisCostKey)
var cost int64
if s, ok := start.(time.Time); ok {
cost = time.Now().Sub(s).Milliseconds()
}
mylogrus.MyLog.Infof("redis cmd: <%s>,err:%v traceId:%v,userId:%v,cost:%v ms", cmd.String(), cmd.Err(), traceId, userId, cost)
return nil
}
func (redisHook) BeforeProcessPipeline(ctx context.Context, cmds []redis.Cmder) (context.Context, error) {
return ctx, nil
}
func (redisHook) AfterProcessPipeline(ctx context.Context, cmds []redis.Cmder) error {
return nil
}
package redisCli
import (
"context"
"hilo-socketCenter/common/mylogrus"
"strconv"
"time"
)
//这个用户避免多个服务器并发问题。
func SetNX(key string, value interface{}, expiration time.Duration, callBack func()) {
flag, err := RedisClient.SetNX(context.Background(), key, value, expiration).Result()
if err != nil {
mylogrus.MyLog.Errorf("key:%v lock start setNx err: %v", key, err)
}
if !flag {
mylogrus.MyLog.Infof("key:%v lock setNx has lock", key)
return
}
mylogrus.MyLog.Infof("key:%v lock setNx begin", key)
callBack()
//执行结束之后,移除key
//RedisClient.Del(context.Background(), key)
mylogrus.MyLog.Infof("key:%v lock setNx end", key)
}
//setNx没有,结束后,没有移除
/*func SetNxNoDel(key string, value interface{}, expiration time.Duration, callBack func()) {
flag, err := RedisClient.SetNX(context.Background(), key, value, expiration).Result()
if err != nil {
mylogrus.MyLog.Errorf("key:%v lock start setNx err: %v", key, err)
}
if !flag {
mylogrus.MyLog.Infof("key:%v lock setNx has lock", key)
return
}
mylogrus.MyLog.Infof("key:%v lock setNx begin", key)
callBack()
mylogrus.MyLog.Infof("key:%v lock setNx end", key)
}*/
func ClearExpired(key string, expireSec int64) error {
return GetRedis().ZRemRangeByScore(context.Background(), key,
"0", strconv.FormatInt(time.Now().Unix()-expireSec, 10)).Err()
}
func Lock(key string, expiration time.Duration) bool {
flag, err := RedisClient.SetNX(context.Background(), key, 1, expiration).Result()
if err != nil {
return false
}
if !flag {
return false
}
return true
}
[DATABASE]
MYSQL_HOST=47.244.34.27:3306
MYSQL_USERNAME=root
MYSQL_PASSWORD=yX0jPAhO0I4s2zlA
MYSQL_DB=hilo
[DATABASECODE]
MYSQL_HOST=47.244.34.27:3306
MYSQL_USERNAME=root
MYSQL_PASSWORD=yX0jPAhO0I4s2zlA
MYSQL_DB=hilo_code
[REDIS]
REDIS_HOST=47.244.34.27:6379
REDIS_PASSWORD=8QZ9JD1zLvPR3yHf
[JWT]
SECRET=hilo1632
ISSUER_API=hiloApi
ISSUER_Mgr=hiloMgr
EXPIRE=240h
[APP]
MASTER=true
BIZ_SECRET=biz
WEB_SECRET=webHilo1258
OPERATION_SECRET=operation1258236
SUPERUSER=2701,2831,4504
OFFICIAL_STAFF=2701,2831,3411,2511
OFFICIAL_GROUP=@TGS#3FDW3MPHZ
MINIMAL_VERSION_ANDROID=22001
MINIMAL_VERSION_IOS=22000
MODERATE=TENCENT
[OSS]
OSS_ACCESS_KEY_ID=LTAIxdazV2pCuV3T
OSS_ACCESS_KEY_SECRET=zuAnreAXQ6vlAKnvvmolFLfb1N5w5S
OSS_ROLE_ARN=acs:ram::1509841556585969:role/aliyunosstokengeneratorrole
OSS_END_POINT=http://oss-accelerate.aliyuncs.com
OSS_BUCKET=starvoice
OSS_CDN=https://oss.chathot.me/
OSS_EXPIRED_TIME=3600
OSS_STS_POINT=me-east-1
OSS_STS=sts-faceline-demo
OSS_STS_AES=484194d4d0f968a7
[AWS]
AWS_BUCKET=starchat
AWS_CDN=https://image.whoisamy.shop/
AWS_DIR=hilo/
CONFIDENCE=80
[RONGYUN]
RONG_CLOUD_APP_KEY=pvxdm17jpe9tr
RONG_CLOUD_APP_SECRET=rI4giiKWaBS4
RONG_CLOUD_URL=https://api-sg01.ronghub.com
[TENCENTYUN]
TENCENTYUN_APP_ID=1400548270
TENCENTYUN_KEY=321bd60f73096b059c7350f1cd97d51028850b34fa58c5c0d26bb4a19e783de8
TX_OVERSEA_APP_ID=40000066
TX_OVERSEA_KEY=3ab68ea5bddc8774d90b8c764ae71188914bd5fd06f30b28790c51e44ca7885c
[EMAS]
REGION_ID=cn-hangzhou
ACCESS_KEY_ID=LTAIdQZv5H1kNZp5
ACCESS_KEY_SECRET=UnwY0ClDkqBMLwPx3OJJiLYyk9xYLO
ANDROID_APP_KEY=30250713
ANDROID_APP_SECRET=cae7b9a9d3e54577d2c3b60bf6d23047
IOS_APP_KEY=30790728
IOS_APP_SECRET=4fd69ca084c67d4b5a8d15452f0af26a
APNS=DEV
[AGORA]
APP_ID=fc3e087f701b4f788099e1924c3cc7b0
APP_CERTIFICATE=ff29c100a613433db82324e8411eabc8
CUSTOMER_KEY=6b132c0ff7164560a2bc53fda06ea85a
CUSTOMER_SECRET=eedad2cd16d24834990d5450ace9f1ce
CALLBACK_SECRET=n_ZizS_N8
[CHECKOUT]
AUTHORIZATION=sk_test_9b5e771c-5a3f-4a8d-a4da-31b19bd43d83
URL=https://api.sandbox.checkout.com/hosted-payments
H5=https://test.chathot.me/action/hiloHtml/22_05_30_recharge/topup.html
HILO_SECRET_KEY=sk_test_dfbaa3b6-135d-4376-9996-2089b7d8a086
[MATCH]
MATCH_FREE_TIME=60
MATCH_FREE_TIME_VIP=60
MATCH_ADD_TIME_FREE=90
MATCH_AGORA_TIME=30
MATCH_CYCLE=8
MATCH_USER_EXPIRES=480
MATCH_SUCCESS_WAIT_DURATION=10
MATCH_SUCCESS_SINGLE_WAIT_TIME_IN_SEC=12
MATCH_SUCCESS_DUAL_WAIT_TIME_IN_SEC=15
[ONLINE]
ONLINE_CYCLE=600
ONLINE_USER_EXPIRES=259200
[VIDEO]
VIDEO_DAILY_FREE_NUM=20
VIDEO_FREE_TIME=60
VIDEO_FREE_TIME_VIP=300
VIDEO_ADD_TIME_FREE=60
VIDEO_AGORA_TIME=30
VIDEO_MINUTE_NORMAL=30
VIDEO_MINUTE_UNION=30
[SESSION]
SESSION_DAILY_FREE_NUM=50
GUILD_USER_HELLO_DAY=30
[BEAN]
DIAMOND_BEAN_RATE=90
[GEM]
DIAMOND_GEM_RATE=10
[H5]
USER_LEVEL=http://test.chathot.me/action/hiloHtml/hiloUserLevel/index.html
GROUP_SUPPORT=http://test.chathot.me/action/activityhtml/21_12_06/page.html
LUCKY_WHEEL=https://test.chathot.me/action/activityhtml/21_12_30/page.html
WEEKLY_STAR=http://test.chathot.me/action/hiloHtml/lxt_h5/page.html
WEEKLY_CP=https://test.chathot.me/action/hiloHtml/Valentines_22_1_18/page.html
COUNTRY_STAR=https://test.chathot.me/action/hiloHtml/22_08_18_nation_star/page.html
NOBLE_BUY_IOS=https://test.chathot.me/action/hiloHtml/22_05_26_buy_nobility/page.html
NOBLE_BUY_IOS_AUDIT=https://test.chathot.me/action/hiloHtml/lxt_h5/page.html
GUILD_DATA_URL=https://test.chathot.me/action/hiloHtml/22_10_18_app_data_coins/index.html
MGR_GUILD_DATA_URL=https://test.chathot.me/action/hiloHtml/22_10_18_app_data_coins/union.html
RANKING_PINK_DIAMOND_URL=https://test.chathot.me/action/activitiesPage/2022_10_17HiloLiveH5/index.html
GROUP_POWER_GRADE_URL=https://test.chathot.me/action/hiloHtml/2023Activity/2023_3_21FamilyLevel/index.html
GROUP_POWER_ACT_URL=
SHEEP_H5_URL=https://gzds.vip/yangyang?game_id=hilo_sheep
ID_URL=https://h5.whoisamy.shop/action/hiloHtml/new_upgrade/index.html
[GROUPIM]
MSG_SORT_EXPIRE=21600
MSG_SORT_SNAP=300
MSG_PARALLEL_SIZE=10
[GRADE]
CHARM_SPEED_VIP=15
ACTITY_SPEED_VIP=15
WEALTH_SPEED_VIP=15
[LIKE]
I_LIKE_NUM=30
I_LIKE_NUM_VIP=300
I_LIKE_NUM_NOBLE=1000
[APPLEPAY]
PASSWORD=38702750a05c4cb09c9d6ca646835634
[REGISTER]
IMEI_TOTAL=3
IMEI_OAUTH=2
ACCOUNT_IP=100
ACCOUNT_IP_DURATION=21600
[BANNER]
GIFT_BANNER_LEVEL1=500
GIFT_BANNER_LEVEL2=2000
GIFT_BANNER_LEVEL3=5000
[DIAMOND]
DAILY_LOGIN_IMEI_LIMIT=2
DAILY_LOGIN_IP_LIMIT=5
PRIVATE_GIFT_RETURN=10
[LUCKY_WHEEL]
MINIMAL_PARTICIPANT=2
WAIT_TIMELONG=10
WINNER_DIAMOND_BANNER=10
[GROUP_CUSTOM_THEME]
PIC_LIMIT=5
DAY=10
[GIFT]
WALL_DIAMOND=10
[DAILY]
LOGIN_COMMON=5
LOGIN_VIP=300
[FRUIT_TYCOON]
POOL_RATIO=80
WATERMELON_RATIO=24
[RISK_CONTROL]
USER_QPS_LIMIT=60
[PAYER_MAX]
URL=https://pay-gate-uat.payermax.com/aggregate-pay-gate/api/gateway
KEY=d50d149a883b8bb6
MERCHANT_ID=SP11018326
BIZ_TYPE=CUSTOMIZE
VERSION=2.3
FRONT_CALLBACK_URL=https://www.hiloconn.com
SHOW_RESULT=1
EXPIRE_TIME=1800
LANGUAGE=en
[PAYPAL]
PAYPAL_CLIENT_ID=AQCXHyXFhNLNWoorcj3Du0J4WwBDy25DoQ7SZKNKRe4PNY0BLpeCzV_zm1HKwAvd7reWeOBCte-vMakM
PAYPAL_SECRET_ID=EDBTK99v6wXhGXhDqDTOksK2j8NPAfJKT-wRTqTrNGrUmn8xsjkrVcO_xSvMVR6CB2bN74rGl_AFm098
RETURN_URL=https://test.apiv1.faceline.live/v1/callback/paypal
\ No newline at end of file
package rpc_m
import (
"encoding/json"
"fmt"
"hilo-socketCenter/common/mylogrus"
"hilo-socketCenter/common/mysql"
"strconv"
"time"
)
type TypeRpc uint8
const (
//MatchConfirm TypeRpc = 101
//CallReady TypeRpc = 102
//AddTimeGift TypeRpc = 103
//AddTimeFree TypeRpc = 104
//RecallWindow TypeRpc = 109
//Video TypeRpc = 110
//VideoCallReady TypeRpc = 111
)
type RpcLog struct {
ID uint64 `gorm:"primary_key"`
Type TypeRpc
UserId string
Msg string
Err string
FailUids string
}
func (RpcLog) TableName() string {
month := time.Now().Format("200601")
return fmt.Sprintf("rpc_log_%s", month)
}
func AddRpcLog(t TypeRpc, userId uint64, msg string, failUids []uint64, err error) {
errStr := ""
if err != nil {
errStr = err.Error()
}
failUidStr, _ := json.Marshal(failUids)
logRpc := RpcLog{
Type: t,
UserId: strconv.FormatUint(userId, 10),
Msg: msg,
Err: errStr,
FailUids: string(failUidStr[:]),
}
if e := mysql.Db.Table(RpcLog{}.TableName()).Create(&logRpc).Error; e != nil {
mylogrus.MyLog.Errorf("log rpc save fail, err:%v", e)
}
}
func AddRpcLogs(t TypeRpc, userIds []uint64, msg string, failUids []uint64, err error) {
errStr := ""
if err != nil {
errStr = err.Error()
}
failUidStr, _ := json.Marshal(failUids)
userIdStr, _ := json.Marshal(userIds)
logRpc := RpcLog{
Type: t,
UserId: string(userIdStr[:]),
Msg: msg,
Err: errStr,
FailUids: string(failUidStr[:]),
}
if e := mysql.Db.Table(RpcLog{}.TableName()).Create(&logRpc).Error; e != nil {
mylogrus.MyLog.Errorf("log rpc save fail, err:%v", e)
}
}
module hilo-socketCenter
go 1.17
require (
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect
github.com/cespare/xxhash/v2 v2.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/fatih/color v1.9.0 // indirect
github.com/go-redis/redis/v8 v8.3.3 // indirect
github.com/go-sql-driver/mysql v1.5.0 // indirect
github.com/golang/protobuf v1.4.3 // indirect
github.com/hashicorp/consul/api v1.7.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.1 // indirect
github.com/hashicorp/go-hclog v0.12.0 // indirect
github.com/hashicorp/go-immutable-radix v1.0.0 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/golang-lru v0.5.0 // indirect
github.com/hashicorp/serf v0.9.3 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.1 // indirect
github.com/joho/godotenv v1.3.0 // indirect
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirect
github.com/lestrrat-go/strftime v1.0.6 // indirect
github.com/mattn/go-colorable v0.1.6 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.1.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 // indirect
github.com/sirupsen/logrus v1.7.0 // indirect
go.opentelemetry.io/otel v0.13.0 // indirect
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0 // indirect
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f // indirect
golang.org/x/text v0.3.3 // indirect
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
google.golang.org/grpc v1.42.0 // indirect
google.golang.org/protobuf v1.25.0 // indirect
gopkg.in/ini.v1 v1.63.2 // indirect
gorm.io/driver/mysql v1.0.3 // indirect
gorm.io/gorm v1.20.12 // indirect
)
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-redis/redis/v8 v8.3.3 h1:e0CL9fsFDK92pkIJH2XAeS/NwO2VuIOAoJvI6yktZFk=
github.com/go-redis/redis/v8 v8.3.3/go.mod h1:jszGxBCez8QA1HWSmQxJO9Y82kNibbUmeYhKWrBejTU=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/consul/api v1.7.0 h1:tGs8Oep67r8CcA2Ycmb/8BLBcJ70St44mF2X10a/qPg=
github.com/hashicorp/consul/api v1.7.0/go.mod h1:1NSuaUUkFaJzMasbfq/11wKYWSR67Xn6r2DXKhuDNFg=
github.com/hashicorp/consul/sdk v0.6.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tkrmZM=
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
github.com/hashicorp/serf v0.9.3 h1:AVF6JDQQens6nMHT9OGERBvK0f8rPrAGILnsKLr6lzM=
github.com/hashicorp/serf v0.9.3/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.1 h1:g39TucaRWyV3dwDO++eEc6qf8TVIQ/Da48WmqjZ3i7E=
github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4=
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ=
github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo=
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
go.opentelemetry.io/otel v0.13.0 h1:2isEnyzjjJZq6r2EKMsFj4TxiQiexsM04AVhwbR/oBA=
go.opentelemetry.io/otel v0.13.0/go.mod h1:dlSNewoRYikTkotEnxdmuBHgzT+k/idJSfDv/FxEnOY=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0 h1:wBouT66WTYFXdxfVdz9sVWARVd/2vfGcmI45D2gj45M=
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.42.0 h1:XT2/MFpuPFsEX2fWh3YQtHkZ+WYZFQRfaUgLZYj/p6A=
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/ini.v1 v1.63.2 h1:tGK/CyBg7SMzb60vP1M03vNZ3VDu3wGQJwn7Sxi9r3c=
gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/mysql v1.0.3 h1:+JKBYPfn1tygR1/of/Fh2T8iwuVwzt+PEJmKaXzMQXg=
gorm.io/driver/mysql v1.0.3/go.mod h1:twGxftLBlFgNVNakL7F+P/x9oYqoymG3YYT8cAfI9oI=
gorm.io/gorm v1.20.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
gorm.io/gorm v1.20.12 h1:ebZ5KrSHzet+sqOCVdH9mTjW91L298nX3v5lVxAzSUY=
gorm.io/gorm v1.20.12/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
[DATABASE]
MYSQL_HOST=47.244.34.27:3306
MYSQL_USERNAME=root
MYSQL_PASSWORD=yX0jPAhO0I4s2zlA
MYSQL_DB=hilo
[DATABASECODE]
MYSQL_HOST=47.244.34.27:3306
MYSQL_USERNAME=root
MYSQL_PASSWORD=yX0jPAhO0I4s2zlA
MYSQL_DB=hilo_code
[REDIS]
REDIS_HOST=47.244.34.27:6379
REDIS_PASSWORD=8QZ9JD1zLvPR3yHf
[JWT]
SECRET=hilo1632
ISSUER_API=hiloApi
ISSUER_Mgr=hiloMgr
EXPIRE=240h
[APP]
MASTER=false
BIZ_SECRET=biz
WEB_SECRET=webHilo1258
OPERATION_SECRET=operation1258236
SUPERUSER=2701,2831
OFFICIAL_STAFF=2701,2831
OFFICIAL_GROUP=@TGS#3NC2ATRHS,@TGS#33W3KNLHK
MINIMAL_VERSION_ANDROID=212
MINIMAL_VERSION_IOS=100
MODERATE=AWS
[OSS]
OSS_ACCESS_KEY_ID=LTAIxdazV2pCuV3T
OSS_ACCESS_KEY_SECRET=zuAnreAXQ6vlAKnvvmolFLfb1N5w5S
OSS_ROLE_ARN=acs:ram::1509841556585969:role/aliyunosstokengeneratorrole
OSS_END_POINT=http://oss-accelerate.aliyuncs.com
OSS_BUCKET=starvoice
OSS_CDN=https://oss.chathot.me/
OSS_EXPIRED_TIME=3600
OSS_STS_POINT=me-east-1
OSS_STS=sts-faceline-demo
OSS_STS_AES=484194d4d0f968a7
[AWS]
AWS_BUCKET=starchat
AWS_CDN=https://image.whoisamy.shop/
AWS_DIR=hilo/
CONFIDENCE=80
[RONGYUN]
RONG_CLOUD_APP_KEY=pvxdm17jpe9tr
RONG_CLOUD_APP_SECRET=rI4giiKWaBS4
RONG_CLOUD_URL=https://api-sg01.ronghub.com
[TENCENTYUN]
TENCENTYUN_APP_ID=1400548270
TENCENTYUN_KEY=321bd60f73096b059c7350f1cd97d51028850b34fa58c5c0d26bb4a19e783de8
TX_OVERSEA_APP_ID=40000066
TX_OVERSEA_KEY=3ab68ea5bddc8774d90b8c764ae71188914bd5fd06f30b28790c51e44ca7885c
[EMAS]
REGION_ID=cn-hangzhou
ACCESS_KEY_ID=LTAI4FhNPzxdzD4w6bHirL9Z
ACCESS_KEY_SECRET=OQvUJpXDrjGi3g1F2aHiAIFWIvLdbP
ANDROID_APP_KEY=30250713
ANDROID_APP_SECRET=cae7b9a9d3e54577d2c3b60bf6d23047
IOS_APP_KEY=30240346
IOS_APP_SECRET=57f33ab9ca6a957a8c659f2b0b6d1205
APNS=DEV
[AGORA]
APP_ID=fc3e087f701b4f788099e1924c3cc7b0
APP_CERTIFICATE=ff29c100a613433db82324e8411eabc8
CUSTOMER_KEY=6b132c0ff7164560a2bc53fda06ea85a
CUSTOMER_SECRET=eedad2cd16d24834990d5450ace9f1ce
CALLBACK_SECRET=n_ZizS_N8
[CHECKOUT]
AUTHORIZATION=sk_test_9b5e771c-5a3f-4a8d-a4da-31b19bd43d83
URL=https://api.sandbox.checkout.com/hosted-payments
H5=http://test.chathot.me/action/hiloHtml/22_05_30_recharge/topup.html
HILO_SECRET_KEY=sk_test_dfbaa3b6-135d-4376-9996-2089b7d8a086
[MATCH]
MATCH_FREE_TIME=60
MATCH_FREE_TIME_VIP=300
MATCH_ADD_TIME_FREE=90
MATCH_AGORA_TIME=30
MATCH_CYCLE=8
MATCH_USER_EXPIRES=480
MATCH_SUCCESS_WAIT_DURATION=10
MATCH_SUCCESS_SINGLE_WAIT_TIME_IN_SEC=12
MATCH_SUCCESS_DUAL_WAIT_TIME_IN_SEC=15
[ONLINE]
ONLINE_CYCLE=600
ONLINE_USER_EXPIRES=259200
[VIDEO]
VIDEO_DAILY_FREE_NUM=20
VIDEO_FREE_TIME=60
VIDEO_FREE_TIME_VIP=300
VIDEO_ADD_TIME_FREE=60
VIDEO_AGORA_TIME=30
VIDEO_MINUTE_NORMAL=1000
VIDEO_MINUTE_UNION=2000
[SESSION]
SESSION_DAILY_FREE_NUM=50
[BEAN]
DIAMOND_BEAN_RATE=90
[GEM]
DIAMOND_GEM_RATE=10
[H5]
USER_LEVEL=http://test.chathot.me/action/activityhtml/hiloUserLevel/index.html
GROUP_SUPPORT=http://test.chathot.me/action/activityhtml/21_12_06/page.html
LUCKY_WHEEL=https://h5.whoisamy.shop/action/activityhtml/21_12_30/page.html
NOBLE_BUY_IOS=https://h5.whoisamy.shop/action/hiloHtml/lxt_h5/page.html
NOBLE_BUY_IOS_AUDIT=https://h5.whoisamy.shop/action/hiloHtml/lxt_h5/page.html
GROUP_POWER_GRADE_URL=https://test.chathot.me/action/hiloHtml/2023Activity/2023_3_21FamilyLevel/index.html
GROUP_POWER_ACT_URL=https://www.baidu.com
SHEEP_H5_URL=https://gzds.vip/yangyang?game_id=hilo_sheep
ID_URL=https://h5.whoisamy.shop/action/hiloHtml/new_upgrade/index.html
[GROUPIM]
MSG_SORT_EXPIRE=43200
MSG_SORT_SNAP=300
[GRADE]
CHARM_SPEED_VIP=15
ACTITY_SPEED_VIP=15
WEALTH_SPEED_VIP=15
[LIKE]
I_LIKE_NUM=30
I_LIKE_NUM_VIP=100
I_LIKE_NUM_NOBLE=1000
[APPLEPAY]
PASSWORD=38702750a05c4cb09c9d6ca646835634
[REGISTER]
IMEI_TOTAL=3
IMEI_OAUTH=2
ACCOUNT_IP=100
ACCOUNT_IP_DURATION=21600
[BANNER]
GIFT_BANNER_LEVEL1=100
GIFT_BANNER_LEVEL2=2000
GIFT_BANNER_LEVEL3=5000
[DIAMOND]
DAILY_LOGIN_IMEI_LIMIT=200
DAILY_LOGIN_IP_LIMIT=5
PRIVATE_GIFT_RETURN=1440
NEW_USER_INVITE_AWARD=5000
[LUCKY_WHEEL]
MINIMAL_PARTICIPANT=2
WAIT_TIMELONG=10
WINNER_DIAMOND_BANNER=100
[GROUP_CUSTOM_THEME]
PIC_LIMIT=5
DAY=10
[GIFT]
WALL_DIAMOND=10
[DAILY]
LOGIN_COMMON=5
LOGIN_VIP=300
[DAILY]
LOGIN_COMMON=5
LOGIN_VIP=300
[FRUIT_TYCOON]
POOL_RATIO=20
WATERMELON_RATIO=70
[ACTIVITY]
COUNTRY_STAR_POOL_RATIO=20
COUNTRY_STAR_ORDINARY_RATIO=20
[PAYER_MAX]
URL=https://pay-gate-uat.payermax.com/aggregate-pay-gate/api/gateway
KEY=d50d149a883b8bb6
MERCHANT_ID=SP11018326
BIZ_TYPE=CUSTOMIZE
VERSION=2.3
FRONT_CALLBACK_URL=https://www.hiloconn.com
SHOW_RESULT=1
EXPIRE_TIME=1800
LANGUAGE=en
\ No newline at end of file
package main
import (
"context"
"encoding/json"
"fmt"
"github.com/go-redis/redis/v8"
"github.com/golang/protobuf/proto"
"github.com/hashicorp/consul/api"
"google.golang.org/grpc"
"google.golang.org/grpc/keepalive"
"google.golang.org/grpc/resolver"
"google.golang.org/grpc/resolver/manual"
"hilo-socketCenter/common"
"hilo-socketCenter/common/consul"
"hilo-socketCenter/common/dingding"
"hilo-socketCenter/common/mylogrus"
"hilo-socketCenter/common/redisCli"
"hilo-socketCenter/domain/model/rpc_m"
"hilo-socketCenter/protocol/userCenter"
"hilo-socketCenter/protocol/userProxy"
"time"
)
const SEND_WORKER = 2000 // 消费端协程数量
const MONITOR_LENGTH = 100 // 队列告警数量
const SocketQueueSendGift = "socket:queue:send_gift"
var userClient userCenter.UserClient
type SendGiftMsg struct {
SendUserId uint64 `json:"sendUserId"`
Msg *userProxy.GlobalGiftBanner `json:"msg"`
}
var sendGiftChan chan *SendGiftMsg
var kacp = keepalive.ClientParameters{
Time: 10 * time.Second, // send pings every 10 seconds if there is no activity
Timeout: time.Second, // wait 1 second for ping ack before considering the connection dead
PermitWithoutStream: true, // send pings even without active streams
}
// 初始化userCenterClient
func init() {
client, err := api.NewClient(api.DefaultConfig()) //非默认情况下需要设置实际的参数
if err != nil {
mylogrus.MyLog.Fatalln(err)
}
cataLog := client.Catalog()
if cataLog == nil {
mylogrus.MyLog.Fatalln("No catalog.")
}
addr, err := consul.GetServices(cataLog, "userCenter")
if err != nil {
mylogrus.MyLog.Fatalln(err)
}
if len(addr) == 0 {
mylogrus.MyLog.Fatalln("No userCenter available.")
}
addresses := make([]resolver.Address, len(addr))
for i, s := range addr {
addresses[i].Addr = s
mylogrus.MyLog.Infof("address : %s", s)
}
r := manual.NewBuilderWithScheme("hilo")
r.InitialState(resolver.State{Addresses: addresses})
userCenterAddr := fmt.Sprintf("%s:///usercenter", r.Scheme())
// Set up addresses connection to the userCenter.
conn, err := grpc.Dial(userCenterAddr,
grpc.WithInsecure(),
grpc.WithBlock(),
grpc.WithKeepaliveParams(kacp),
grpc.WithResolvers(r),
grpc.WithDefaultServiceConfig("{ \"loadBalancingPolicy\": \"round_robin\" }"))
if err != nil {
mylogrus.MyLog.Fatalf("did not connect: %v", err)
}
//defer conn.Close()
userClient = userCenter.NewUserClient(conn)
if userClient == nil {
mylogrus.MyLog.Fatalln("userClient null")
}
}
func main() {
mylogrus.MyLog.Infof("cron sendGiftChan start")
// 8核 n send + 4 blpop
sendGiftChan = make(chan *SendGiftMsg, SEND_WORKER)
for i := 0; i < 4; i++ {
go func() {
deal()
}()
}
for i := 0; i < SEND_WORKER; i++ {
go func() {
send()
}()
}
go check()
select {}
}
func check() {
tick := time.NewTicker(time.Second * 3)
defer tick.Stop()
for {
select {
case <-tick.C:
l, err := redisCli.GetRedis().LLen(context.Background(), SocketQueueSendGift).Result()
if err != nil {
mylogrus.MyLog.Infof("cron sendGiftChan msg error,left %v-%v", l, err)
}
if l > MONITOR_LENGTH {
go func() {
if sErr := dingding.SendDingRobot(dingding.ROBOTWEBHOOK, fmt.Sprintf("送礼横幅变化通知延迟,队列%s长度:%d", SocketQueueSendGift, l), true); sErr != nil {
mylogrus.MyLog.Errorf("dingding msg fail:%v", sErr)
}
}()
}
if l > 0 {
mylogrus.MyLog.Infof("cron sendGiftChan msg,left %v", l)
}
}
}
}
func deal() {
for true {
//不需要加锁,注意,阻塞。
strs, err := redisCli.GetRedis().BLPop(context.Background(), time.Second, SocketQueueSendGift).Result()
if err != nil {
if err != redis.Nil {
mylogrus.MyLog.Errorf("cron sendGiftChan redisCli.GetRedis().BLPop err:+%v", err)
}
}
if len(strs) >= 2 {
content := strs[1]
mylogrus.MyLog.Infof("cron sendGiftChan content:%v", content)
msg := new(SendGiftMsg)
if err := json.Unmarshal([]byte(content), msg); err != nil {
mylogrus.MyLog.Errorf("cron sendGiftChan Unmarshal err:%+v, content:%v", err, content)
}
sendGiftChan <- msg
}
}
}
//var limiter = rate.NewLimiter(2000, 2000)
func send() {
for msg := range sendGiftChan {
//if err := limiter.Wait(context.Background()); err == nil {
SendToUserCenter(msg.SendUserId, msg.Msg)
//}
}
}
// SendToUserCenter 发送群信令。入参是内部imGroupId,这里做转换
func SendToUserCenter(sendUserId uint64, msg *userProxy.GlobalGiftBanner) {
if buffer, err := proto.Marshal(msg); err == nil {
rspUids, err := broadcast(common.MsgTypeGlobalGiftBanner, buffer)
//记录socket,注意闭包问题
go func(userId uint64, msg *userProxy.GlobalGiftBanner, rspUids []uint64, err error) {
buf, _ := json.Marshal(msg)
rpc_m.AddRpcLog(common.MsgTypeGlobalGiftBanner, userId, string(buf[:]), rspUids, err)
}(sendUserId, msg, rspUids, err)
if err != nil {
mylogrus.MyLog.Errorf("grpc GlobalGiftBanner send fail")
} else {
mylogrus.MyLog.Info("grpc GlobalGiftBanner send success")
}
} else {
}
}
//广播
func broadcast(msgType uint32, data []byte) ([]uint64, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer cancel()
rsp, err := userClient.Broadcast(ctx, &userCenter.BroadcastMessage{
MsgType: msgType,
PayLoad: data,
})
if err != nil {
mylogrus.MyLog.Errorf("broadcast message failed %s", err.Error())
}
if rsp != nil {
mylogrus.MyLog.Infof("broadcast message res:%v", rsp)
return rsp.FailedUids, err
} else {
return []uint64{}, err
}
}
syntax = "proto3";
package userCenter;
option go_package = "protocol/userCenter";
/* id = 1 */
message RouteMessage {
uint64 uid = 1;
uint32 msgType = 2;
bytes payLoad = 3;
}
/* id = 2 */
message RouteMessageRsp {
uint32 status = 1;
}
/* id = 3 */
message LoginMessage {
string proxyAddr = 1; // userProxy的地址:ip:port
string token = 2;
string clientAddr = 3; // 客户端地址(websocket):ip:port
}
/* id = 4 */
message LoginMessageRsp {
uint32 status = 1;
uint64 uid = 2;
}
/* id = 5 */
message LogoutMessage {
string clientAddr = 1; // 客户端地址(websocket):ip:port
uint64 uid = 2;
}
/* id = 6 */
message LogoutMessageRsp {
uint32 status = 1;
}
/* id = 7 */
message MulticastMessage {
repeated uint64 uids = 1;
uint32 msgType = 2;
bytes payLoad = 3;
}
/* id = 8 */
message MulticastMessageRsp {
repeated uint64 failedUids = 1;
}
/* id = 9 */
message KickMessage {
uint64 uid = 1;
string addr = 2;
}
/* id = 10 */
message KickMessageRsp {
uint32 status = 1;
}
/* id = 11 */
message BroadcastMessage {
uint32 msgType = 2;
bytes payLoad = 3;
}
/* id = 12 */
message BroadcastMessageRsp {
repeated uint64 failedUids = 1;
}
/* id = 13 */
message BizMessage {
uint64 uid = 1;
uint32 msgType = 2;
string payLoad = 3;
}
/* id = 14 */
message BizMessageRsp {
uint32 status = 1;
}
service Router {
rpc route(RouteMessage) returns (RouteMessageRsp) {}
rpc kickUser(KickMessage) returns (KickMessageRsp) {}
}
service User {
rpc login(LoginMessage) returns (LoginMessageRsp) {}
rpc logout(LogoutMessage) returns (LogoutMessageRsp) {}
rpc multicast(MulticastMessage) returns (MulticastMessageRsp) {}
rpc broadcast(BroadcastMessage) returns (BroadcastMessageRsp) {}
rpc transmit(BizMessage) returns (BizMessageRsp) {}
}
\ No newline at end of file
syntax = "proto3";
package userProxy;
option go_package = "protocol/userProxy";
/* user*/
message User {
uint64 id = 1;
string externalId = 2;
string nick = 3;
string avatar = 4;
string country = 5;
string countryIcon = 6;
uint64 birthday = 7;
bool isVip = 8;
bool isLike = 9;
bool isLikeMe = 10;
}
/* Svip*/
message Svip {
uint64 svipLevel = 1;
repeated SvipPrivilege privileges = 2;
}
message SvipPrivilege {
int32 type = 1;
bool canSwitch = 2;
bool userSwitch = 3;
string mysteryCode = 4;
}
/* id = 1 登录*/
message Login {
string token = 1;
}
/* id = 2 登录的回应 */
message LoginRsp {
uint32 status = 1;
}
/* id = 3 客户端心跳 */
message HeartBeat {
string externalUid = 1;
}
/* id = 4 客户端心跳的回应 */
message HeartBeatRsp {
uint32 status = 1;
}
/* id = 7 客户端上行消息 */
message BizRequest {
uint32 type = 1;
string payLoad = 2;
}
/* id = 8 客户端上行消息的应答 */
message BizResponse {
uint32 status = 1;
}
/* id == 100 | 140 匹配结果通知 waitDuration:开始/下一个时间 matchUniqueId:匹配一对的唯一标识码, status:是否是落单 singleWaitTimeInSec:单方等待连接最长时间 dualWaitTimeInSec:双方连接中最长时间*/
message MatchSuccess {
string localUserId = 1;
string remoteUserId = 2;
uint32 waitDuration = 3;
string matchUniqueId = 4;
bool status = 5;
uint32 singleWaitTimeInSec = 6;
uint32 dualWaitTimeInSec = 7;
User remoteUser = 8;
}
/* id == 101 匹配后用户选择结果通知, failType: 只有status=2 才有值,其它为0,failType=1:等待时间到了,拒绝 failType=2:主动拒绝 */
message MatchConfirm {
uint32 status = 1;
string channelId = 2;
string token = 3;
string localUserId = 4;
string remoteUserId = 5;
uint32 remoteAgoraId = 6;
uint32 callDuration = 7;
uint32 localAgoraId = 8;
uint32 diamondBalance = 9;
string matchUniqueId = 10;
uint32 failType = 11;
}
/* id == 102 视频通话准备 */
message CallReady {
uint64 startTimestamp = 1;
uint64 endTimestamp = 2;
uint64 callDuration = 3;
string channelId = 4;
uint64 remainDiamond = 5;
}
/* id == 103 礼物加时 */
message AddTimeGift {
uint32 giftId = 1;
string token = 2;
uint32 duration = 3;
uint64 endTimestamp = 4;
string channelId = 5;
bool isSender = 6;
uint32 giftNum = 7;
string iconUrl = 8;
string svgaUrl = 9;
string senderAvatar = 10;
string receiverAvatar = 11;
}
/* id == 104 免费加时 */
message AddTimeFree {
string token = 1;
uint32 duration = 2;
uint64 endTimestamp = 3;
string channelId = 4;
uint32 senderAgoraId = 5;
}
/* id == 105 退出 */
message ConnectsQuit {
uint64 from_user_id = 1;
}
/* id == 106 连接状态 */
message ConnectStatus {
uint64 from_user_id = 1;
float user_diamonds = 2;
bool diamonds_enough = 3;
}
/* id == 107 ??? */
message ConnectsCall {
uint64 from_user_id = 1;
string rong_room_name = 2;
bool is_join = 3;
}
/* id == 108 */
message ConnectCommon {
string rong_room_name = 1;
uint64 from_user_id = 2;
string extra = 3;
string message = 4;
}
/* id == 109 召回授权弹框 */
message RecallWindow {
}
/* id == 110 | 132 视频发送 status:(1:接收到邀请, 2:接收到对方同意, 3:双方拒绝(还没接通), 4:对方挂断(接通后)diamondBalance 只有status=2,才出现)*/
message Video {
string videoUniqueId = 1;
string channelId = 2;
uint32 localAgoraId = 3;
uint32 remoteAgoraId = 4;
string agoraToken = 5;
string sendUserId = 6;
string receiveUserId = 7;
uint32 status = 8;
uint32 diamondBalance = 9;
User sendUser = 10;
}
/* id == 111 视频通话准备 */
message VideoCallReady {
uint64 startTimestamp = 1;
uint64 endTimestamp = 2;
uint64 callDuration = 3;
string channelId = 4;
uint64 remainDiamond = 5;
}
/* id == 112 互相喜欢 */
message LikeEach {
string remoteUserId = 1;
}
/* id == 113 喜欢我 */
message LikeMe {
string remoteUserId = 1;
string remoteNick = 2;
string channelId = 3;
}
/* id == 114 日常进入app,获取钻石 */
message DailyInAppDiamond {
uint32 diamondNum = 1;
}
/* id == 115 横幅 */
message GlobalGiftBanner {
uint32 bannerLevel = 1;
uint64 giftId = 2;
uint32 giftNum = 3;
string sendUserId = 4;
string receiveUserId = 5;
string groupId = 6;
string sendUserCode = 7;
string sendUserAvatar = 8;
string sendUserNick = 9;
string receiveUserNick = 10;
string giftPicUrl = 11;
Svip svip = 12;
Svip receiveSvip = 13;
}
/* id == 116 横幅的回应,用来测量RTT */
message GlobalGiftBannerRsp {
uint32 bannerLevel = 1;
uint64 giftId = 2;
uint32 giftNum = 3;
string sendUserId = 4;
string receiveUserId = 5;
string groupId = 6;
}
/*id==117 幸运转盘通知,客户端重新拉取查询, type:客户端不用理*/
message LuckyWheel {
string groupId = 1;
uint32 type = 2;
}
/* id == 118 幸运转盘获胜者全服广播 */
message LuckyWheelBanner {
uint32 diamondNum = 1;
string sendUserId = 2;
string groupId = 3;
string nick = 4;
string code = 5;
string avatar = 6;
Svip svip = 7;
}
/* id == 119 幸运转盘钻石变化 */
message LuckyWheelDiamondChange {
string groupId = 1;
}
/* id == 120 服务器配置变更 */
message ConfigChange {
uint32 type = 1;
}
/* id == 121 全局火箭横幅 */
message GlobalRocketNotice {
string groupId = 1;
string period = 2;
uint32 round = 3;
uint32 stage = 4;
string topUserIcon = 5;
string nick = 6;
string code = 7;
string avatar = 8;
Svip svip = 9;
}
/* id == 122 群发功能弹窗 */
message GroupSendNotice {
string senderExtId = 1;
string senderCode = 2;
uint32 senderSex = 3;
string senderAvatar = 4;
string text = 5;
string groupName = 6;
string groupCode = 7;
string groupAvatar = 8;
uint32 userInNum = 9; // 最近进入房间的人数
string groupId = 10;
}
/* id == 123 全球消息 */
message GlobalBroadcast {
string senderExtId = 1;
string senderCode = 2;
uint32 senderSex = 3;
string senderAvatar = 4;
string senderNick = 5;
string msg = 6;
string groupId = 7;
uint32 senderNobleLevel = 8;
}
/* id == 124 全球消息 */
message MicTaskFinish {
string userId = 1;
uint32 diamond = 2;
}
/* id == 125 水果机开奖通知 */
message FruitMachine {
string date = 1;
uint32 round = 2;
}
/* id == 126 贵族变化 */
message NobleChange {
}
/* id == 127 加入群组成功 */
message JoinGroup {
string groupId = 1;
string externalId = 2;
}
/* id == 128 1对1视频1分钟加时成功 */
message VideoTimeMinuteSuccess {
string token = 1;
uint32 duration = 2;
uint64 endTimestamp = 3;
string channelId = 4;
uint32 senderAgoraId = 5;
string videoUniqueId = 6;
bool isSend = 7;
uint32 sendRemainDiamond = 8;
}
/* id == 129 1对1视频1分钟加时询问检查 */
message VideoTimeMinuteCheck {
string videoUniqueId = 1;
uint32 diamond = 2;
string uuid = 3;
}
/* id == 130 1对1视频,错过 */
message VideoMiss {
uint32 totalNum = 1;
}
/* id == 131 进房,群组活动信息 */
message GroupActivity {
string ActivityId = 1;// id
uint64 StartAt = 2; // 开始时间戳,东八区时间戳
uint64 EndAt = 3; // 结束时间戳,东八区时间戳
string Banner = 4; // banner url
int32 AcType = 5; // 类型1.游戏2.比赛3.排队4.诗歌
string Theme = 6; // 活动主题
int32 PersonNum = 7; // 订阅人数
bool IsSubscribe = 8; // 我是否订阅该活动
string GroupId = 9; // 群id
}
/* id == 144 邀请用户成为房间会员 */
message RoomInviteMember {
string group_id = 1;
}
\ No newline at end of file
[DATABASE]
MYSQL_HOST=ua4papc3hmgqf351pbej-rw4rm.rwlb.dubai.rds.aliyuncs.com
MYSQL_USERNAME=nextvideo
MYSQL_PASSWORD=ihlUwI4nhi9W88MI
MYSQL_DB=hilo
[DATABASECODE]
MYSQL_HOST=ua4papc3hmgqf351pbej-rw4rm.rwlb.dubai.rds.aliyuncs.com
MYSQL_USERNAME=nextvideo
MYSQL_PASSWORD=ihlUwI4nhi9W88MI
MYSQL_DB=hilo_code
[REDIS]
REDIS_HOST=r-eb3btxn8vfdsuwdbuf.redis.dubai.rds.aliyuncs.com:6379
REDIS_PASSWORD=
[JWT]
SECRET=hilo1504
ISSUER_API=hiloApi
ISSUER_Mgr=hiloMgr
EXPIRE=720h
[APP]
MASTER=true
BIZ_SECRET=biz
OPERATION_SECRET=operation1258236
WEB_SECRET=webHilo1258
SUPERUSER=28201,23951,133101,41,2020531,955271,1575531
OFFICIAL_STAFF=133101,435731,486461,41
OFFICIAL_GROUP=@TGS#33W3KNLHK,@TGS#3XA5RJ5HH,@TGS#3O6PKBTH6
MINIMAL_VERSION_ANDROID=22600
MINIMAL_VERSION_IOS=22600
ROOM_MODE=AVChatRoom
MODERATE=TENCENT
[OSS]
OSS_ACCESS_KEY_ID=LTAIxdazV2pCuV3T
OSS_ACCESS_KEY_SECRET=zuAnreAXQ6vlAKnvvmolFLfb1N5w5S
OSS_ROLE_ARN=acs:ram::1509841556585969:role/aliyunosstokengeneratorrole
OSS_END_POINT=https://oss-accelerate.aliyuncs.com
OSS_BUCKET=starvoice
OSS_CDN=https://oss.chathot.me/
OSS_EXPIRED_TIME=3600
OSS_STS_POINT=me-east-1
OSS_STS=sts-faceline-demo
OSS_STS_AES=484194d4d0f968a7
[AWS]
AWS_BUCKET=starchat
AWS_CDN=https://image.whoisamy.shop/
AWS_DIR=hilo/
CONFIDENCE=80
[RONGYUN]
RONG_CLOUD_APP_KEY=uwd1c0sxu5t41
RONG_CLOUD_APP_SECRET=vo9djozyBl9bZ
RONG_CLOUD_URL=https://api-sg01.ronghub.com
[TENCENTYUN]
TENCENTYUN_APP_ID=1400487464
TENCENTYUN_KEY=cb4c1f2e3398a88e0e9468b403f671e60d66a564df86f7db925c6ab4f18b66e5
TX_OVERSEA_APP_ID=40000066
TX_OVERSEA_KEY=3ab68ea5bddc8774d90b8c764ae71188914bd5fd06f30b28790c51e44ca7885c
[EMAS]
REGION_ID=cn-hangzhou
ACCESS_KEY_ID=LTAIdQZv5H1kNZp5
ACCESS_KEY_SECRET=UnwY0ClDkqBMLwPx3OJJiLYyk9xYLO
ANDROID_APP_KEY=30774987
ANDROID_APP_SECRET=297a0f231f1286a2de9aab097cc8ff5c
IOS_APP_KEY=30790728
IOS_APP_SECRET=4fd69ca084c67d4b5a8d15452f0af26a
APNS=PRODUCT
[AGORA]
APP_ID=6291d069123642d9929a49c734c50719
APP_CERTIFICATE=d5de40350aa54e60bcdce90c71e9598a
CUSTOMER_KEY=6b132c0ff7164560a2bc53fda06ea85a
CUSTOMER_SECRET=eedad2cd16d24834990d5450ace9f1ce
[CHECKOUT]
AUTHORIZATION=sk_fca6e213-b7df-4bd7-99f4-7c0a9f7c778c
URL=https://api.checkout.com/hosted-payments
H5=https://h5.whoisamy.shop/action/hiloHtml/22_05_30_recharge/topup.html
HILO_SECRET_KEY=sk_26806bf4-e6e3-45e2-a093-c72c5b53eaf5
[MATCH]
MATCH_FREE_TIME=60
MATCH_FREE_TIME_VIP=60
MATCH_ADD_TIME_FREE=90
MATCH_AGORA_TIME=30
MATCH_CYCLE=8
MATCH_USER_EXPIRES=480
MATCH_SUCCESS_WAIT_DURATION=10
MATCH_SUCCESS_SINGLE_WAIT_TIME_IN_SEC=12
MATCH_SUCCESS_DUAL_WAIT_TIME_IN_SEC=15
[ONLINE]
ONLINE_CYCLE=600
ONLINE_USER_EXPIRES=259200
[VIDEO]
VIDEO_DAILY_FREE_NUM=20
VIDEO_FREE_TIME=60
VIDEO_FREE_TIME_VIP=300
VIDEO_ADD_TIME_FREE=60
VIDEO_AGORA_TIME=30
VIDEO_MINUTE_NORMAL=60
VIDEO_MINUTE_UNION=60
[SESSION]
SESSION_DAILY_FREE_NUM=50
GUILD_USER_HELLO_DAY=30
[BEAN]
DIAMOND_BEAN_RATE=90
[GEM]
DIAMOND_GEM_RATE=10
[H5]
USER_LEVEL=https://h5.whoisamy.shop/action/hiloHtml/hiloUserLevel/index.html
GROUP_SUPPORT=https://h5.whoisamy.shop/action/activityhtml/21_12_06/page.html
LUCKY_WHEEL=https://h5.whoisamy.shop/action/activityhtml/21_12_30/page.html
WEEKLY_STAR=https://h5.whoisamy.shop/action/hiloHtml/lxt_h5/page.html
WEEKLY_CP=https://h5.whoisamy.shop/action/hiloHtml/Valentines_22_1_18/page.html
COUNTRY_STAR=https://h5.whoisamy.shop/action/hiloHtml/22_08_18_nation_star/page.html
NOBLE_BUY_IOS=https://h5.whoisamy.shop/action/hiloHtml/22_05_26_buy_nobility/page.html
NOBLE_BUY_IOS_AUDIT=https://h5.whoisamy.shop/action/hiloHtml/lxt_h5/page.html
GUILD_DATA_URL=https://h5.whoisamy.shop/action/hiloHtml/22_10_18_app_data_coins/index.html
MGR_GUILD_DATA_URL=https://h5.whoisamy.shop/action/hiloHtml/22_10_18_app_data_coins/union.html
RANKING_PINK_DIAMOND_URL=https://h5.whoisamy.shop/action/activitiesPage/2022_10_17HiloLiveH5/index.html
GROUP_POWER_GRADE_URL=https://h5.whoisamy.shop/action/hiloHtml/2023Activity/2023_3_21FamilyLevel/index.html
ID_URL=https://h5.whoisamy.shop/action/hiloHtml/new_upgrade/index.html
GROUP_POWER_ACT_URL=https://h5.whoisamy.shop/action/hiloHtml/2023Activity/2023_4_21FamilyMonth/index.html
SHEEP_H5_URL=https://h5.whoisamy.shop/action/slotRelease/sheep0322v1/index.html?game_id=hilo_sheep
[GROUPIM]
MSG_SORT_EXPIRE=1209600
MSG_SORT_SNAP=300
MSG_PARALLEL_SIZE=10
[GRADE]
CHARM_SPEED_VIP=15
ACTITY_SPEED_VIP=15
WEALTH_SPEED_VIP=15
[LIKE]
I_LIKE_NUM=500
I_LIKE_NUM_VIP=1000
I_LIKE_NUM_NOBLE=5000
[APPLEPAY]
PASSWORD=38702750a05c4cb09c9d6ca646835634
[REGISTER]
IMEI_TOTAL=5
IMEI_OAUTH=2
ACCOUNT_IP=100
ACCOUNT_IP_DURATION=21600
[BANNER]
GIFT_BANNER_LEVEL1=3000
GIFT_BANNER_LEVEL2=5000
GIFT_BANNER_LEVEL3=10000
[DIAMOND]
DAILY_LOGIN_IMEI_LIMIT=5
DAILY_LOGIN_IP_LIMIT=30
PRIVATE_GIFT_RETURN=1440
NEW_USER_INVITE_AWARD=5000
[LUCKY_WHEEL]
MINIMAL_PARTICIPANT=2
WAIT_TIMELONG=10
WINNER_DIAMOND_BANNER=200
[GROUP_CUSTOM_THEME]
PIC_LIMIT=50
DAY=10
[GIFT]
WALL_DIAMOND=2000
[DAILY]
LOGIN_COMMON=10
LOGIN_VIP=1000
[FRUIT_TYCOON]
BIG_WINNER_THRESDHOLD=30000
BIG_WINNER_LOW=10000
BIG_WINNER_HIGH=20000
POOL_RATIO=5
WATERMELON_RATIO=24
[ACTIVITY]
COUNTRY_STAR_POOL_RATIO=20
COUNTRY_STAR_ORDINARY_RATIO=20
[RISK_CONTROL]
USER_QPS_LIMIT=128
USER_URL_QPS_LIMIT=64
[PAYER_MAX]
URL=https://pay-gate.payermax.com/aggregate-pay-gate/api/gateway
KEY=503a970695756efa
MERCHANT_ID=SP11018326
BIZ_TYPE=CUSTOMIZE
VERSION=2.3
FRONT_CALLBACK_URL=https://www.hiloconn.com
SHOW_RESULT=1
EXPIRE_TIME=1800
LANGUAGE=en
[PAYPAL]
PAYPAL_CLIENT_ID=AXn-z2U6D2uKW0eJBoH3Hg0MzH6i8mLackAP9bcub2W_YmfMC-YBuPD3sTQgwJSecmAVtHIS9IsqBiIy
PAYPAL_SECRET_ID=EBNCFnSEwbteb8TDVtCMcOUcQBimG7hABmSe0bgC05HriWmje7cKFV2F4xI9pZnt1hDetKLnYxfmWYSY
RETURN_URL=https://apiv1.faceline.live/v1/callback/paypal
\ No newline at end of file
#!/usr/bin/bash
if [ $# -lt 1 ]
then
echo "Parameters missing."
echo "Usage: $0 <executable name>"
exit
fi
while :
do
$1
printf "$(date) : $1 return $?, wait for 5 seconds to restart\n"
sleep 5
done
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment