...
 
Commits (17)
......@@ -17,6 +17,10 @@ func AppIsRelease() bool {
return GetMode() == RELEASE
}
func AppIsLocal() bool {
return GetMode() == LOCAL
}
//数据库的配置
type MysqlConfig struct {
MYSQL_HOST string
......@@ -36,274 +40,8 @@ type MysqlCodeConfig struct {
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
REDIS_CLUSTER_HOST string
REDIS_CLUSTER_PASSWORD string
}
const (
......@@ -313,43 +51,18 @@ const (
)
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 GetConfigRedis() RedisConfig {
return redisConfigData
}
func init() {
str, _ := os.Getwd()
logrus.New().Info(str)
......@@ -383,171 +96,7 @@ func init() {
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)
}
}
......@@ -24,7 +24,7 @@ func init() {
filenamePrefix = logDir + filepath.Base(os.Args[0]) + "."
// stderr日志重定向
MyLog.SetOutput(os.Stdout)
RewriteStderrFile()
//RewriteStderrFile()
if config.AppIsRelease() {
MyLog.SetFormatter(&logrus.JSONFormatter{
......
[DATABASE]
MYSQL_HOST=47.244.34.27:3306
MYSQL_USERNAME=root
MYSQL_PASSWORD=yX0jPAhO0I4s2zlA
MYSQL_HOST=hk-cynosdbmysql-grp-a3wqck8p.sql.tencentcdb.com:22303
MYSQL_USERNAME=hilo_test
MYSQL_PASSWORD=cPsTMSA9szQ6B9Y2zFXSvpDdduB8kZxC
MYSQL_DB=hilo
[DATABASECODE]
MYSQL_HOST=47.244.34.27:3306
MYSQL_USERNAME=root
MYSQL_PASSWORD=yX0jPAhO0I4s2zlA
MYSQL_HOST=hk-cynosdbmysql-grp-a3wqck8p.sql.tencentcdb.com:22303
MYSQL_USERNAME=hilo_test
MYSQL_PASSWORD=cPsTMSA9szQ6B9Y2zFXSvpDdduB8kZxC
MYSQL_DB=hilo_code
[REDIS]
REDIS_HOST=47.244.34.27:6379
REDIS_PASSWORD=8QZ9JD1zLvPR3yHf
REDIS_HOST=172.19.0.2:6379
REDIS_PASSWORD=yPyZH1DYMJhrVQgr
REDIS_CLUSTER_HOST=172.19.0.2:6379
REDIS_CLUSTER_PASSWORD=yPyZH1DYMJhrVQgr
[JWT]
SECRET=hilo1632
ISSUER_API=hiloApi
ISSUER_Mgr=hiloMgr
EXPIRE=240h
\ No newline at end of file
[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
[DATABASE]
MYSQL_HOST=47.244.34.27:3306
MYSQL_USERNAME=root
MYSQL_PASSWORD=yX0jPAhO0I4s2zlA
MYSQL_HOST=hk-cynosdbmysql-grp-a3wqck8p.sql.tencentcdb.com:22303
MYSQL_USERNAME=hilo_test
MYSQL_PASSWORD=cPsTMSA9szQ6B9Y2zFXSvpDdduB8kZxC
MYSQL_DB=hilo
[DATABASECODE]
MYSQL_HOST=47.244.34.27:3306
MYSQL_USERNAME=root
MYSQL_PASSWORD=yX0jPAhO0I4s2zlA
MYSQL_HOST=hk-cynosdbmysql-grp-a3wqck8p.sql.tencentcdb.com:22303
MYSQL_USERNAME=hilo_test
MYSQL_PASSWORD=cPsTMSA9szQ6B9Y2zFXSvpDdduB8kZxC
MYSQL_DB=hilo_code
[REDIS]
REDIS_HOST=47.244.34.27:6379
REDIS_PASSWORD=8QZ9JD1zLvPR3yHf
REDIS_HOST=43.135.4.137:6379
REDIS_PASSWORD=yPyZH1DYMJhrVQgr
REDIS_CLUSTER_HOST=43.135.4.137:6379
REDIS_CLUSTER_PASSWORD=yPyZH1DYMJhrVQgr
[JWT]
SECRET=hilo1632
ISSUER_API=hiloApi
ISSUER_Mgr=hiloMgr
EXPIRE=240h
\ No newline at end of file
[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
......@@ -2,17 +2,17 @@ package main
import (
"context"
"errors"
"flag"
"fmt"
"github.com/golang/protobuf/proto"
"gorm.io/gorm/schema"
"net"
"net/http"
"net/url"
"os"
"strconv"
"time"
"github.com/go-redis/redis/v8"
consulapi "github.com/hashicorp/consul/api"
"google.golang.org/grpc"
"google.golang.org/grpc/keepalive"
"gorm.io/driver/mysql"
......@@ -20,6 +20,7 @@ import (
"gorm.io/gorm/logger"
"hilo-userCenter/common"
appConfig "hilo-userCenter/common/config"
"hilo-userCenter/common/dingding"
"hilo-userCenter/common/mylogrus"
"hilo-userCenter/manager"
......@@ -29,8 +30,6 @@ import (
const (
port = 50040
default_redis_address = "47.244.34.27:6379"
default_redis_password = "8QZ9JD1zLvPR3yHf"
redis_section = 1
)
......@@ -39,11 +38,15 @@ const (
monitorLength = 3500 // 队列告警数量
kickChanSize = 500
broadcastChanSize = 3500
areacastChanSize = 3500
levelcastChanSize = 3500
)
var (
kickChan chan KickChanMsg
broadcastChan chan BroadcastChanMsg
areacastChan chan AreaChanMsg
levelcastChan chan LevelChanMsg
)
type KickChanMsg struct {
......@@ -57,14 +60,24 @@ type BroadcastChanMsg struct {
in *userCenter.BroadcastMessage
}
type AreaChanMsg struct {
ProxyAddr string
UserIds []uint64
in *userCenter.AreaMessage
}
type LevelChanMsg struct {
ProxyAddr string
UserIds []uint64
in *userCenter.LevelMessage
}
var (
userManager *manager.UserManager = nil
termManager *manager.TerminalManager = nil
roomManager *manager.RoomManager = nil
)
var logDir = "/var/log/hilo/"
type server struct {
userCenter.UnimplementedUserServer
}
......@@ -78,7 +91,7 @@ var kasp = keepalive.ServerParameters{
}
func (s *server) Login(ctx context.Context, in *userCenter.LoginMessage) (*userCenter.LoginMessageRsp, error) {
mylogrus.MyLog.Infof("Received loginMsg: %s, from proxy %s, client %s\n", in.Token, in.ProxyAddr, in.ClientAddr)
//mylogrus.MyLog.Infof("Received loginMsg: %s, from proxy %s, client %s\n", in.Token, in.ProxyAddr, in.ClientAddr)
var loginStatus uint32 = common.Login_success
claim, err := common.ParseToken(in.GetToken())
......@@ -95,7 +108,7 @@ func (s *server) Login(ctx context.Context, in *userCenter.LoginMessage) (*userC
// FIXME: 发现用户已经登录,要踢走旧连接
proxyAddr := userManager.GetUser(claim.UserId)
if proxyAddr != nil {
mylogrus.MyLog.Infof("%d has existing value %s", claim.UserId, *proxyAddr)
//mylogrus.MyLog.Infof("%d has existing value %s", claim.UserId, *proxyAddr)
kickChan <- KickChanMsg{
userId: claim.UserId,
proxyAddr: *proxyAddr,
......@@ -116,7 +129,7 @@ func (s *server) Login(ctx context.Context, in *userCenter.LoginMessage) (*userC
} else {
mylogrus.MyLog.Errorf("wrong user %d", claim.UserId)
}
mylogrus.MyLog.Infof("adding user %d", claim.UserId)
//mylogrus.MyLog.Infof("adding user %d", claim.UserId)
// save to redis
userManager.AddUser(claim.UserId, in.ProxyAddr)
......@@ -179,13 +192,13 @@ func (s *server) Multicast(ctx context.Context, in *userCenter.MulticastMessage)
failed = append(failed, uid)
}
}
if len(failed) > 0 {
mylogrus.MyLog.Infof("Multicast failed for %v\n", failed)
}
//if len(failed) > 0 {
//mylogrus.MyLog.Infof("Multicast failed for %v\n", failed)
//}
return &userCenter.MulticastMessageRsp{FailedUids: failed}, nil
}
func (s *server) Broadcast(ctx context.Context, in *userCenter.BroadcastMessage) (*userCenter.BroadcastMessageRsp, error) {
func (s *server) BroadcastOld(ctx context.Context, in *userCenter.BroadcastMessage) (*userCenter.BroadcastMessageRsp, error) {
//mylogrus.MyLog.Infof("Broadcasting msgType = %d, size = %d\n", in.MsgType, len(in.PayLoad))
failed := []uint64{}
......@@ -238,6 +251,139 @@ func (s *server) Broadcast(ctx context.Context, in *userCenter.BroadcastMessage)
return &userCenter.BroadcastMessageRsp{FailedUids: failed}, nil
}
func (s *server) Broadcast(ctx context.Context, in *userCenter.BroadcastMessage) (*userCenter.BroadcastMessageRsp, error) {
redisKey := "service:userSocket"
ipPorts, err := rdbCluster.ZRangeByScore(context.Background(), redisKey, &redis.ZRangeBy{
Min: fmt.Sprintf("%d", time.Now().Add(-time.Second*15).Unix()), // 3倍心跳
Max: "+inf",
}).Result()
if err != nil {
failMsg := fmt.Sprintf("get service fail,svc:%v,err:%v", "userSocket", err)
mylogrus.MyLog.Errorf(failMsg)
_ = dingding.SendDingRobot(dingding.ROBOTWEBHOOK, failMsg, true)
return nil, err
}
if len(ipPorts) <= 0 {
failMsg := fmt.Sprintf("get service empty,svc:%v,err:%v", "userSocket", err)
mylogrus.MyLog.Errorf(failMsg)
_ = dingding.SendDingRobot(dingding.ROBOTWEBHOOK, failMsg, true)
return nil, errors.New(failMsg)
}
data, _ := proto.Marshal(in)
for _, ip := range ipPorts {
queue := "broadcast:" + ip
rdbCluster.RPush(context.Background(), queue, data)
}
return &userCenter.BroadcastMessageRsp{FailedUids: nil}, nil
}
func (s *server) Areacast(ctx context.Context, in *userCenter.AreaMessage) (*userCenter.AreaMessageRsp, error) {
var failed []uint64
terminals := termManager.GetAll()
if terminals != nil {
var uids []uint64
for uidStr := range *terminals {
if uid, _ := strconv.ParseUint(uidStr, 10, 64); uid > 0 {
uids = append(uids, uid)
}
}
// 处理分区用户
areaUids := userManager.GetAreaUsers(uids, int8(in.Area))
if len(areaUids) <= 0 {
return &userCenter.AreaMessageRsp{FailedUids: failed}, nil
}
m := make(map[string][]uint64, 0)
for uid := range areaUids {
ok := false
addr := userManager.GetUser(uid)
if addr != nil {
if _, ok := m[*addr]; !ok {
m[*addr] = make([]uint64, 0)
}
m[*addr] = append(m[*addr], uid)
ok = true
} else {
mylogrus.MyLog.Errorf("Unknown user %d\n", uid)
}
if !ok {
failed = append(failed, uid)
}
}
for addr, users := range m {
const sendBatchSize = 5
for i := 0; i < len(users); i += sendBatchSize {
end := i + sendBatchSize
if end > len(users) {
end = len(users)
}
areacastChan <- AreaChanMsg{
ProxyAddr: addr,
UserIds: users[i:end],
in: in,
}
}
}
}
return &userCenter.AreaMessageRsp{FailedUids: failed}, nil
}
func (s *server) Levelcast(ctx context.Context, in *userCenter.LevelMessage) (*userCenter.LevelMessageRsp, error) {
var failed []uint64
terminals := termManager.GetAll()
if terminals != nil {
var uids []uint64
for uidStr := range *terminals {
if uid, _ := strconv.ParseUint(uidStr, 10, 64); uid > 0 {
uids = append(uids, uid)
}
}
// 处理等级用户
levelUserIds, userIds := userManager.GetLevelUsers(uids, in.Level)
if len(levelUserIds) <= 0 {
return &userCenter.LevelMessageRsp{FailedUids: failed}, nil
}
if in.Area > 0 {
// 处理分区用户
levelUserIds = userManager.GetAreaUsers(userIds, int8(in.Area))
if len(levelUserIds) <= 0 {
return &userCenter.LevelMessageRsp{FailedUids: failed}, nil
}
}
m := make(map[string][]uint64, 0)
for uid := range levelUserIds {
ok := false
addr := userManager.GetUser(uid)
if addr != nil {
if _, ok := m[*addr]; !ok {
m[*addr] = make([]uint64, 0)
}
m[*addr] = append(m[*addr], uid)
ok = true
} else {
mylogrus.MyLog.Errorf("Unknown user %d\n", uid)
}
if !ok {
failed = append(failed, uid)
}
}
for addr, users := range m {
const sendBatchSize = 5
for i := 0; i < len(users); i += sendBatchSize {
end := i + sendBatchSize
if end > len(users) {
end = len(users)
}
levelcastChan <- LevelChanMsg{
ProxyAddr: addr,
UserIds: users[i:end],
in: in,
}
}
}
}
return &userCenter.LevelMessageRsp{FailedUids: failed}, nil
}
func (s *server) Transmit(ctx context.Context, in *userCenter.BizMessage) (*userCenter.BizMessageRsp, error) {
mylogrus.MyLog.Infof("Transmiting msgType = %d, uid = %d, payLoad: %s\n", in.MsgType, in.Uid, in.PayLoad)
......@@ -312,6 +458,38 @@ func realBroadcast(addr string, uids []uint64, msg *userCenter.BroadcastMessage)
}
}
func realAreacast(addr string, uids []uint64, msg *userCenter.AreaMessage) {
for _, uid := range uids {
client := manager.UserProxyMgr.MakeClient(addr)
if client == nil {
mylogrus.MyLog.Errorf("Failed in making client for %d, %s\n", uid, addr)
} else {
toRouterClient := userCenter.NewRouterClient(client)
status, err := routeMessage(toRouterClient, uid, msg.MsgType, msg.PayLoad)
if err != nil {
mylogrus.MyLog.Errorf("routeMessage uid = %d, msgType = %d, status = %d, %v", uid, msg.MsgType, status, err)
}
}
}
}
func realLevelcast(addr string, uids []uint64, msg *userCenter.LevelMessage) {
for _, uid := range uids {
client := manager.UserProxyMgr.MakeClient(addr)
if client == nil {
mylogrus.MyLog.Errorf("Failed in making client for %d, %s\n", uid, addr)
} else {
toRouterClient := userCenter.NewRouterClient(client)
status, err := routeMessage(toRouterClient, uid, msg.MsgType, msg.PayLoad)
if err != nil {
mylogrus.MyLog.Errorf("routeMessage uid = %d, msgType = %d, status = %d, %v", uid, msg.MsgType, status, err)
}
}
}
}
func routeMessage(c userCenter.RouterClient, uid uint64, msgType uint32, data []byte) (uint32, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer cancel()
......@@ -346,7 +524,7 @@ func transmitMessage(c biz.TransmitterClient, msgType uint32, data string) (uint
}
func sendKickMessage(c userCenter.RouterClient, msg *userCenter.KickMessage) error {
mylogrus.MyLog.Infof("sendKickMessage %s", msg.String())
//mylogrus.MyLog.Infof("sendKickMessage %s", msg.String())
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer cancel()
r, err := c.KickUser(ctx, msg)
......@@ -356,151 +534,80 @@ func sendKickMessage(c userCenter.RouterClient, msg *userCenter.KickMessage) err
return err
}
func consulCheck(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "consulCheck")
}
const (
RegisterName = "userCenter"
RegisterTag = "用户中心"
)
func registerToConsul(client *consulapi.Client, retry bool) {
checkPort := port + 1000
registration := new(consulapi.AgentServiceRegistration)
hostName, _ := os.Hostname()
registration.ID = fmt.Sprintf("%s-%s", RegisterName, hostName)
registration.Name = RegisterName
registration.Port = port
registration.Tags = []string{RegisterTag}
myIp, myNodeName := "", ""
if localIp, err := common.GetClientIpV2(); err != nil {
mylogrus.MyLog.Fatalln("local ip not found", err)
} else {
myIp = localIp
func RegisterToRedis(RedisClusterClient *redis.Client, port int, init bool) {
// 本地不注册
if appConfig.AppIsLocal() {
return
}
mylogrus.MyLog.Infof("My ip is %s, nodeName: %s\n", myIp, myNodeName)
registration.Address = myIp
registration.Check = &consulapi.AgentServiceCheck{
HTTP: fmt.Sprintf("http://localhost:%d%s", checkPort, "/check"),
Timeout: "3s",
Interval: "5s",
DeregisterCriticalServiceAfter: "30s", //check失败后30秒删除本服务
if RedisClusterClient == nil {
failMsg := fmt.Sprintf("RegisterToRedis fail,redisClusterNotInit,serviceName:%v", RegisterName)
_ = dingding.SendDingRobot(dingding.ROBOTWEBHOOK, failMsg, true)
mylogrus.MyLog.Errorf(failMsg)
return
}
err := client.Agent().ServiceRegister(registration)
redisKey := "service:" + RegisterName
ip, err := common.GetClientIpV2()
if err != nil {
mylogrus.MyLog.Fatal("register server error : ", err)
}
if !retry {
http.HandleFunc("/check", consulCheck)
http.ListenAndServe(fmt.Sprintf(":%d", checkPort), nil)
}
}
// 自愈检查
// 启动后每一分钟检查一次
// 首次启动不执行
func selfCheck() {
ticker := time.NewTicker(time.Minute)
failMsg := fmt.Sprintf("RegisterToRedis fail,ip fail,err:%v,serviceName:%v", err, RegisterName)
mylogrus.MyLog.Errorf(failMsg)
_ = dingding.SendDingRobot(dingding.ROBOTWEBHOOK, failMsg, true)
return
}
ipPort := fmt.Sprintf("%s:%d", ip, port)
if err := RedisClusterClient.ZAdd(context.Background(), redisKey, &redis.Z{
Score: float64(time.Now().Unix()),
Member: ipPort,
}).Err(); err != nil {
failMsg := fmt.Sprintf("RegisterToRedis fail,redis fail,err:%v,serviceName:%v", err, RegisterName)
mylogrus.MyLog.Errorf(failMsg)
_ = dingding.SendDingRobot(dingding.ROBOTWEBHOOK, failMsg, true)
}
// 初始化注册自我检查 selfCheck
if init {
go func() {
ticker := time.NewTicker(time.Second * 5)
defer ticker.Stop()
for {
select {
case <-ticker.C:
client, err := consulapi.NewClient(consulapi.DefaultConfig()) //非默认情况下需要设置实际的参数
if err != nil {
mylogrus.MyLog.Errorf("RegisterToConsul Fail:%v", err)
break
}
if client == nil {
mylogrus.MyLog.Errorf("Fail to get consul client.")
break
}
cataLog := client.Catalog()
if cataLog == nil {
mylogrus.MyLog.Errorf("No catalog.")
break
}
services, _, err := cataLog.Service(RegisterName, "", nil)
if err != nil {
mylogrus.MyLog.Errorf("%v", err)
break
}
if len(services) == 0 {
mylogrus.MyLog.Errorf("%s not found.", RegisterName)
go registerToConsul(client, true) // 重新注册
} else {
mylogrus.MyLog.Infof("%s check success %v", RegisterName, services[0])
RegisterToRedis(RedisClusterClient, port, false) // 刷新注册
}
}
}()
}
}
type HiloConfig struct {
type HiloConfigs struct {
Name string `gorm:"primary_key"`
Value string
}
var rdbCluster *redis.Client
func main() {
flag.Parse()
config := consulapi.DefaultConfig()
client, err := consulapi.NewClient(config)
if err != nil {
mylogrus.MyLog.Fatal("consul client error : ", err)
}
go registerToConsul(client, false)
go selfCheck()
redisAddress := default_redis_address
redisPassword := default_redis_password
mysqHost, mysqlUsername, mysqlPassword, mysqlDb := "47.244.34.27:3306", "root", "yX0jPAhO0I4s2zlA", "hilo"
kv := client.KV()
if kv != nil {
p, _, err := kv.Get("redis_address", nil)
if err == nil && p != nil {
redisAddress = string(p.Value)
}
p, _, err = kv.Get("redis_password", nil)
if err == nil && p != nil {
redisPassword = string(p.Value)
}
p, _, err = kv.Get("mysql_host", nil)
if err == nil && p != nil {
mysqHost = string(p.Value)
}
p, _, err = kv.Get("mysql_username", nil)
if err == nil && p != nil {
mysqlUsername = string(p.Value)
}
p, _, err = kv.Get("mysql_password", nil)
if err == nil && p != nil {
mysqlPassword = string(p.Value)
}
p, _, err = kv.Get("mysql_db", nil)
if err == nil && p != nil {
mysqlDb = string(p.Value)
}
}
mylogrus.MyLog.Infof("Db config mysqHost = %v , mysqlUsername = %v, mysqlPassword = %v ,mysqlDb = %v redisAddress :%v,redisPassword:%v",
mysqHost, mysqlUsername, mysqlPassword, mysqlDb, redisAddress, redisPassword)
if mysqHost == "" || mysqlUsername == "" || mysqlPassword == "" || mysqlDb == "" {
mylogrus.MyLog.Fatalln("Db config is missing.")
}
// init redis cluster
rdbCluster = redis.NewClient(&redis.Options{
Addr: appConfig.GetConfigRedis().REDIS_CLUSTER_HOST,
Password: appConfig.GetConfigRedis().REDIS_CLUSTER_PASSWORD,
})
// 注册到redis
RegisterToRedis(rdbCluster, port, true)
// init redis
rdb := redis.NewClient(&redis.Options{
Addr: redisAddress,
Password: redisPassword,
Addr: appConfig.GetConfigRedis().REDIS_HOST,
Password: appConfig.GetConfigRedis().REDIS_PASSWORD,
DB: redis_section,
})
if rdb == nil {
mylogrus.MyLog.Fatalf("failed to connect redis %s\n", redisAddress)
mylogrus.MyLog.Fatalf("failed to connect redis %s\n", appConfig.GetConfigRedis().REDIS_HOST)
}
result, err := rdb.Ping(context.Background()).Result()
if err != nil {
mylogrus.MyLog.Fatal(err)
......@@ -512,9 +619,12 @@ func main() {
options := "?charset=utf8mb4&parseTime=True&loc=Local&time_zone=" + url.QueryEscape("'+8:00'")
fmt.Println("options = ", options)
dsn := mysqlUsername + ":" + mysqlPassword + "@(" + mysqHost + ")/" + mysqlDb
dsn := appConfig.GetConfigMysql().MYSQL_USERNAME + ":" + appConfig.GetConfigMysql().MYSQL_PASSWORD + "@(" + appConfig.GetConfigMysql().MYSQL_HOST + ")/" + appConfig.GetConfigMysql().MYSQL_DB
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
Logger: logger.Default.LogMode(logger.Info),
NamingStrategy: schema.NamingStrategy{
SingularTable: true,
},
})
if err != nil {
mylogrus.MyLog.Fatal("mysql connect error %v", err)
......@@ -522,7 +632,7 @@ func main() {
mylogrus.MyLog.Infof("mysql connect success")
}
var jwtConfig = HiloConfig{}
var jwtConfig = HiloConfigs{}
db.First(&jwtConfig, "name = 'jwt_secret'")
if len(jwtConfig.Value) == 0 {
mylogrus.MyLog.Fatalln("Empty jwt secret")
......@@ -533,7 +643,15 @@ func main() {
userManager = &manager.UserManager{
Ctx: context.Background(),
RedisClient: rdb,
MysqlDB: db,
}
go func() {
for {
// 同步区域
userManager.SyncArea()
time.Sleep(time.Minute * 15)
}
}()
termManager = &manager.TerminalManager{
Ctx: context.Background(),
RedisClient: rdb,
......@@ -543,16 +661,14 @@ func main() {
RedisClient: rdb,
}
mylogrus.MyLog.Infof("Connected to Redis %s\n", redisAddress)
go func() {
ticker := time.NewTicker(time.Second * 30)
defer ticker.Stop()
for {
select {
case a := <-ticker.C:
mylogrus.MyLog.Infof("Tick at %s", a.String())
case <-ticker.C:
//mylogrus.MyLog.Infof("Tick at %s", a.String())
terminals := termManager.GetAll()
if terminals != nil {
if len(*terminals) <= 100 {
......@@ -569,6 +685,8 @@ func main() {
// 初始化协程chan
kickChan = make(chan KickChanMsg, kickChanSize)
broadcastChan = make(chan BroadcastChanMsg, broadcastChanSize)
areacastChan = make(chan AreaChanMsg, areacastChanSize)
levelcastChan = make(chan LevelChanMsg, levelcastChanSize)
go check() // 检查长度
for i := 0; i < kickChanSize; i++ {
go func(n int) {
......@@ -580,6 +698,16 @@ func main() {
broadcast(n)
}(i)
}
for i := 0; i < areacastChanSize; i++ {
go func(n int) {
areacast(n)
}(i)
}
for i := 0; i < levelcastChanSize; i++ {
go func(n int) {
levelcast(n)
}(i)
}
fmt.Println("Go RPC listening on ", port)
lis, err := net.Listen("tcp4", ":"+strconv.Itoa(port))
......@@ -595,10 +723,10 @@ func main() {
func kick(n int) {
for msg := range kickChan {
mylogrus.MyLog.Infof("handling kick in:%d,msg:%+v", n, msg)
//mylogrus.MyLog.Infof("handling kick in:%d,msg:%+v", n, msg)
clientAddr := termManager.GetTerminal(msg.userId)
if clientAddr == nil {
mylogrus.MyLog.Errorf("No terminal found for %d", msg.userId)
//mylogrus.MyLog.Errorf("No terminal found for %d", msg.userId)
} else {
client := manager.UserProxyMgr.GetClient(msg.proxyAddr)
if client == nil {
......@@ -622,6 +750,18 @@ func broadcast(n int) {
}
}
func areacast(n int) {
for msg := range areacastChan {
realAreacast(msg.ProxyAddr, msg.UserIds, msg.in)
}
}
func levelcast(n int) {
for msg := range levelcastChan {
realLevelcast(msg.ProxyAddr, msg.UserIds, msg.in)
}
}
var lastDingTime time.Time
var dingIntervalMin float64 = 5 // 5min 告警间隔
......@@ -632,11 +772,12 @@ func check() {
for {
select {
case <-tick.C:
l, l2 := len(kickChan), len(broadcastChan)
if l >= monitorLength || l2 >= monitorLength {
l, l2, l3, l4 := len(kickChan), len(broadcastChan), len(areacastChan), len(levelcastChan)
if l >= monitorLength || l2 >= monitorLength || l3 >= monitorLength || l4 >= monitorLength {
if time.Now().Sub(lastDingTime).Minutes() > dingIntervalMin {
go func() {
if sErr := dingding.SendDingRobot(dingding.ROBOTWEBHOOK, fmt.Sprintf("userCenter通知延迟,队列长度:kickChan:%d,broadcastChan:%d", l, l2), true); sErr != nil {
if sErr := dingding.SendDingRobot(dingding.ROBOTWEBHOOK, fmt.Sprintf("userCenter通知延迟,队列长度:kickChan:%d,broadcastChan:%d,areacastChan:%d,levelcastChan:%d",
l, l2, l3, l4), true); sErr != nil {
mylogrus.MyLog.Errorf("dingding msg fail:%v", sErr)
} else {
lastDingTime = time.Now()
......
......@@ -3,8 +3,11 @@ package manager
import (
"context"
"github.com/go-redis/redis/v8"
"gorm.io/gorm"
"hilo-userCenter/common/mylogrus"
"log"
"strconv"
"sync"
)
const (
......@@ -14,6 +17,7 @@ const (
type UserManager struct {
Ctx context.Context
RedisClient *redis.Client
MysqlDB *gorm.DB
}
func (m *UserManager) GetUser(uid uint64) *string {
......@@ -63,3 +67,102 @@ func (m *UserManager) GetAll() *map[string]string {
return &result
}
}
// 国家到area映射 country->area 1:阿语 2:非阿语
var countryArea sync.Map
type ResCountry struct {
Name string
Area int8
}
// 定期同步国家到area映射
func (m *UserManager) SyncArea() {
var rows []ResCountry
if err := m.MysqlDB.Model(ResCountry{}).Find(&rows).Error; err != nil {
mylogrus.MyLog.Errorf("SyncArea fail:%v", err)
return
}
for _, v := range rows {
countryArea.Store(v.Name, v.Area)
}
}
// 获取地区
func (m *UserManager) GetArea(country string) (area int8) {
area = 1 // 默认阿语
if data, ok := countryArea.Load(country); ok {
return data.(int8)
}
return area
}
type UserTinyArea struct {
ID uint64
Avatar string
ExternalId string
Sex uint8
Code string
Country string
Area int8 `gorm:"-"`
}
// 获取指定区域用户
func (m *UserManager) GetAreaUsers(userIds []uint64, area int8) map[uint64]UserTinyArea {
res := make(map[uint64]UserTinyArea)
// 从db中读,暂时不缓存(几千个)
var users []UserTinyArea
if err := m.MysqlDB.Table("user").
Select("id,external_id,sex,code,country,avatar").
Where("id IN (?)", userIds).Find(&users).Error; err != nil {
mylogrus.MyLog.Errorf("GetUserArea fail:%v", err)
return res
}
for _, u := range users {
a := m.GetArea(u.Country)
if a != area {
continue
}
res[u.ID] = UserTinyArea{
ID: u.ID,
ExternalId: u.ExternalId,
Sex: u.Sex,
Code: u.Code,
Country: u.Country,
Area: a,
Avatar: u.Avatar,
}
}
return res
}
// 获取财富等级大于某等级的用户
// 开区间
func (m *UserManager) GetLevelUsers(userIds []uint64, wealthLevel int32) (map[uint64]UserTinyArea, []uint64) {
res := make(map[uint64]UserTinyArea)
var resIds []uint64
// 从db中读,暂时不缓存(几千个)
var users []UserTinyArea
if err := m.MysqlDB.Table("user").Joins("JOIN match_wealth_user_score ON match_wealth_user_score.user_id = user.id").
Select("user.id,external_id,sex,code,country,avatar").
Where("user.id IN (?)", userIds).
Where("match_wealth_user_score.grade > ?", wealthLevel).
Find(&users).Error; err != nil {
mylogrus.MyLog.Errorf("GetLevelUsers fail:%v", err)
return res, resIds
}
for _, u := range users {
a := m.GetArea(u.Country)
res[u.ID] = UserTinyArea{
ID: u.ID,
ExternalId: u.ExternalId,
Sex: u.Sex,
Code: u.Code,
Country: u.Country,
Area: a,
Avatar: u.Avatar,
}
resIds = append(resIds, u.ID)
}
return res, resIds
}
......@@ -122,6 +122,27 @@ message GetLastRoomHeartbeatMessageResp {
int64 timestamp = 1;
}
message AreaMessage {
int32 area = 1;
uint32 msgType = 2;
bytes payLoad = 3;
}
message AreaMessageRsp {
repeated uint64 failedUids = 1;
}
message LevelMessage {
int32 level = 1;
uint32 msgType = 2;
bytes payLoad = 3;
int32 area = 4;
}
message LevelMessageRsp {
repeated uint64 failedUids = 1;
}
service Router {
rpc route(RouteMessage) returns (RouteMessageRsp) {}
rpc kickUser(KickMessage) returns (KickMessageRsp) {}
......@@ -132,6 +153,8 @@ service User {
rpc logout(LogoutMessage) returns (LogoutMessageRsp) {}
rpc multicast(MulticastMessage) returns (MulticastMessageRsp) {}
rpc broadcast(BroadcastMessage) returns (BroadcastMessageRsp) {}
rpc areacast(AreaMessage) returns (AreaMessageRsp) {}
rpc levelcast(LevelMessage) returns (LevelMessageRsp) {}
rpc transmit(BizMessage) returns (BizMessageRsp) {}
rpc enterRoom(EnterRoomMessage) returns (EnterRoomMessageRsp) {}
rpc leaveRoom(LeaveRoomMessage) returns (LeaveRoomMessageRsp) {}
......
......@@ -86,7 +86,6 @@ message MatchConfirm {
uint32 remoteAgoraId = 6;
uint32 callDuration = 7;
uint32 localAgoraId = 8;
uint32 diamondBalance = 9;
string matchUniqueId = 10;
uint32 failType = 11;
}
......@@ -97,62 +96,6 @@ message CallReady {
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,才出现)*/
......@@ -165,17 +108,19 @@ message Video {
string sendUserId = 6;
string receiveUserId = 7;
uint32 status = 8;
uint32 diamondBalance = 9;
User sendUser = 10;
}
/* id == 109 召回授权弹框 */
message RecallWindow {
}
/* id == 111 视频通话准备 */
message VideoCallReady {
uint64 startTimestamp = 1;
uint64 endTimestamp = 2;
uint64 callDuration = 3;
string channelId = 4;
uint64 remainDiamond = 5;
}
/* id == 112 互相喜欢 */
......@@ -213,6 +158,7 @@ message GlobalGiftBanner {
uint32 bannerType = 14; // 类型:0.普通礼物 1.cp直接送礼 2.cp告白礼物
uint32 cpLevel = 15; // cp等级
string receiveUserAvatar = 16;
uint32 nobleLevel = 17; // 贵族等级
}
/* id == 116 横幅的回应,用来测量RTT */
......@@ -289,6 +235,7 @@ message GlobalBroadcast {
string msg = 6;
string groupId = 7;
uint32 senderNobleLevel = 8;
bool isPinned = 9;
}
/* id == 124 全球消息 */
......@@ -322,13 +269,11 @@ message VideoTimeMinuteSuccess {
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;
}
......@@ -369,6 +314,7 @@ message GlobalGameBanner {
uint64 diamond = 4;
string bannerUrl = 5;
uint64 gameId = 6; // 1.ludo 2.uno 3.dice 4.lucky wheel 5.lucky box 6.fruit 7.slot
bool isPink = 7; // 是否粉钻
}
/* id == 147 羊羊匹配成功 */
......@@ -377,6 +323,11 @@ message SheepMatchSuccess {
User user = 2;
User otherUser = 3;
uint64 game_id = 4;
string channelId = 5;
string token = 6;
uint32 agoraId = 7;
uint32 provider = 8;
uint32 otherAgoraId = 9;
}
message SheepGamePlayer {
......@@ -464,3 +415,33 @@ message MicUserData {
string headwearIcon = 15;
Svip svip = 16;
}
/* id == 157 游戏大厅匹配成功 */
message LobbyMatchSuccess {
uint64 game_id = 1;
uint64 mode = 2;
string group_id = 3;
User user = 4;
User otherUser = 5;
string gameCode = 6;
}
/* id == 158 H5游戏静音 */
message H5GameVoiceMute {
}
/* id == 159 H5游戏打开语音 */
message H5GameVoiceUnMute {
}
/* id == 160 退出房间 */
message QuitRoom {
uint32 reason = 1; // 原因1.被拉黑;2.被踢出
string group_id = 2;
}
/* id == 161 国家管理员横幅 */
message GlobalCountryMgrBanner {
string country = 1; // 国家
User user = 2; // 用户信息
}
\ No newline at end of file
[DATABASE]
MYSQL_HOST=ua4papc3hmgqf351pbej-rw4rm.rwlb.dubai.rds.aliyuncs.com
MYSQL_USERNAME=nextvideo
MYSQL_PASSWORD=ihlUwI4nhi9W88MI
MYSQL_HOST=172.28.16.44
MYSQL_USERNAME=hilo_master
MYSQL_PASSWORD=o8NNd8F7e6On2RqIgOhsy1PsiSxROT3n
MYSQL_DB=hilo
[DATABASECODE]
MYSQL_HOST=ua4papc3hmgqf351pbej-rw4rm.rwlb.dubai.rds.aliyuncs.com
MYSQL_USERNAME=nextvideo
MYSQL_PASSWORD=ihlUwI4nhi9W88MI
MYSQL_HOST=172.28.16.44
MYSQL_USERNAME=hilo_master
MYSQL_PASSWORD=o8NNd8F7e6On2RqIgOhsy1PsiSxROT3n
MYSQL_DB=hilo_code
[REDIS]
REDIS_HOST=r-eb3btxn8vfdsuwdbuf.redis.dubai.rds.aliyuncs.com:6379
REDIS_HOST=172.28.16.31:6379
REDIS_PASSWORD=
REDIS_CLUSTER_HOST=172.28.16.47:6379
REDIS_CLUSTER_PASSWORD=
[JWT]
SECRET=hilo1504
ISSUER_API=hiloApi
ISSUER_Mgr=hiloMgr
EXPIRE=720h
\ No newline at end of file
[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