mirror of
https://github.com/genxium/DelayNoMore
synced 2025-10-09 08:36:52 +00:00
Initial commit.
This commit is contained in:
155
battle_srv/common/conf.go
Normal file
155
battle_srv/common/conf.go
Normal file
@@ -0,0 +1,155 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// 隐式导入
|
||||
var Conf *config
|
||||
|
||||
const (
|
||||
APP_NAME = "server"
|
||||
SERVER_ENV_PROD = "PROD"
|
||||
SERVER_ENV_TEST = "TEST"
|
||||
)
|
||||
|
||||
type generalConf struct {
|
||||
AppRoot string `json:"-"`
|
||||
ConfDir string `json:"-"`
|
||||
TestEnvSQLitePath string `json:"-"`
|
||||
PreConfSQLitePath string `json:"-"`
|
||||
ServerEnv string `json:"-"`
|
||||
}
|
||||
|
||||
type mysqlConf struct {
|
||||
DSN string `json:"-"`
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Dbname string `json:"dbname"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type sioConf struct {
|
||||
HostAndPort string `json:"hostAndPort"`
|
||||
}
|
||||
|
||||
type botServerConf struct {
|
||||
SecondsBeforeSummoning int `json:"secondsBeforeSummoning"`
|
||||
Protocol string `json:"protocol"`
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
SymmetricKey string `json:"symmetricKey"`
|
||||
}
|
||||
|
||||
type redisConf struct {
|
||||
Dbname int `json:"dbname"`
|
||||
Host string `json:"host"`
|
||||
Password string `json:"password"`
|
||||
Port int `json:"port"`
|
||||
}
|
||||
|
||||
type config struct {
|
||||
General *generalConf
|
||||
MySQL *mysqlConf
|
||||
Sio *sioConf
|
||||
Redis *redisConf
|
||||
BotServer *botServerConf
|
||||
}
|
||||
|
||||
func MustParseConfig() {
|
||||
Conf = &config{
|
||||
General: new(generalConf),
|
||||
MySQL: new(mysqlConf),
|
||||
Sio: new(sioConf),
|
||||
Redis: new(redisConf),
|
||||
BotServer: new(botServerConf),
|
||||
}
|
||||
execPath, err := os.Executable()
|
||||
ErrFatal(err)
|
||||
|
||||
pwd, err := os.Getwd()
|
||||
Logger.Debug("os.GetWd", zap.String("pwd", pwd))
|
||||
ErrFatal(err)
|
||||
|
||||
appRoot := pwd
|
||||
confDir := filepath.Join(appRoot, "configs")
|
||||
Logger.Debug("conf", zap.String("dir", confDir))
|
||||
if isNotExist(confDir) {
|
||||
appRoot = filepath.Dir(execPath)
|
||||
confDir = filepath.Join(appRoot, "configs")
|
||||
Logger.Debug("conf", zap.String("dir", confDir))
|
||||
if isNotExist(confDir) {
|
||||
i := strings.LastIndex(pwd, "battle_srv")
|
||||
if i == -1 {
|
||||
Logger.Fatal("无法找到配置目录,cp -rn configs.template configs,并配置相关参数,再启动")
|
||||
}
|
||||
appRoot = pwd[:(i + 10)]
|
||||
confDir = filepath.Join(appRoot, "configs")
|
||||
Logger.Debug("conf", zap.String("dir", confDir))
|
||||
if isNotExist(confDir) {
|
||||
Logger.Fatal("无法找到配置目录,cp -rn configs.template configs,并配置相关参数,再启动")
|
||||
}
|
||||
}
|
||||
}
|
||||
Conf.General.AppRoot = appRoot
|
||||
testEnvSQLitePath := filepath.Join(confDir, "test_env.sqlite")
|
||||
if !isNotExist(testEnvSQLitePath) {
|
||||
Conf.General.TestEnvSQLitePath = testEnvSQLitePath
|
||||
}
|
||||
preConfSQLitePath := filepath.Join(confDir, "pre_conf_data.sqlite")
|
||||
if !isNotExist(preConfSQLitePath) {
|
||||
Conf.General.PreConfSQLitePath = preConfSQLitePath
|
||||
}
|
||||
Conf.General.ConfDir = confDir
|
||||
Conf.General.ServerEnv = os.Getenv("ServerEnv")
|
||||
|
||||
loadJSON("mysql.json", Conf.MySQL)
|
||||
setMySQLDSNURL(Conf.MySQL)
|
||||
loadJSON("sio.json", Conf.Sio)
|
||||
loadJSON("redis.json", Conf.Redis)
|
||||
loadJSON("bot_server.json", Conf.BotServer)
|
||||
}
|
||||
|
||||
func setMySQLDSNURL(c *mysqlConf) {
|
||||
var dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s",
|
||||
c.Username, c.Password, c.Host, c.Port, c.Dbname)
|
||||
c.DSN = dsn
|
||||
|
||||
}
|
||||
|
||||
func loadJSON(fp string, v interface{}) {
|
||||
if !filepath.IsAbs(fp) {
|
||||
fp = filepath.Join(Conf.General.ConfDir, fp)
|
||||
}
|
||||
_, err := os.Stat(fp)
|
||||
ErrFatal(err)
|
||||
|
||||
fd, err := os.Open(fp)
|
||||
ErrFatal(err)
|
||||
defer fd.Close()
|
||||
Logger.Info("Opened json file successfully.", zap.String("fp", fp))
|
||||
err = json.NewDecoder(fd).Decode(v)
|
||||
ErrFatal(err)
|
||||
Logger.Info("Loaded json file successfully.", zap.String("fp", fp))
|
||||
}
|
||||
|
||||
// Please only use this auxiliary function before server is fully started up, but not afterwards (启动过程可以使用,运行时不准使用).
|
||||
func ErrFatal(err error) {
|
||||
if err != nil {
|
||||
Logger.Fatal("ErrFatal", zap.NamedError("err", err))
|
||||
}
|
||||
}
|
||||
|
||||
func isNotExist(p string) bool {
|
||||
if _, err := os.Stat(p); err != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
67
battle_srv/common/constants.json
Normal file
67
battle_srv/common/constants.json
Normal file
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"RET_CODE": {
|
||||
"__comment__":"基础",
|
||||
"OK": 9000,
|
||||
"UNKNOWN_ERROR": 9001,
|
||||
"INVALID_REQUEST_PARAM": 9002,
|
||||
"IS_TEST_ACC": 9003,
|
||||
"MYSQL_ERROR": 9004,
|
||||
"NONEXISTENT_ACT": 9005,
|
||||
"LACK_OF_DIAMOND": 9006,
|
||||
"LACK_OF_GOLD": 9007,
|
||||
"LACK_OF_ENERGY": 9008,
|
||||
"NONEXISTENT_ACT_HANDLER": 9009,
|
||||
"LOCALLY_NO_AVAILABLE_ROOM": 9010,
|
||||
"LOCALLY_NO_SPECIFIED_ROOM": 9011,
|
||||
"PLAYER_NOT_ADDABLE_TO_ROOM": 9012,
|
||||
"PLAYER_NOT_READDABLE_TO_ROOM": 9013,
|
||||
"PLAYER_NOT_FOUND": 9014,
|
||||
"PLAYER_CHEATING": 9015,
|
||||
"WECHAT_SERVER_ERROR": 9016,
|
||||
"IS_BOT_ACC": 9017,
|
||||
|
||||
"__comment__":"SMS",
|
||||
"SMS_CAPTCHA_REQUESTED_TOO_FREQUENTLY": 5001,
|
||||
"SMS_CAPTCHA_NOT_MATCH": 5002,
|
||||
"INVALID_TOKEN": 2001,
|
||||
|
||||
"DUPLICATED": 2002,
|
||||
"INCORRECT_HANDLE": 2004,
|
||||
|
||||
"INCORRECT_PASSWORD": 2006,
|
||||
"INCORRECT_CAPTCHA": 2007,
|
||||
"INVALID_EMAIL_LITERAL": 2008,
|
||||
"NO_ASSOCIATED_EMAIL": 2009,
|
||||
"SEND_EMAIL_TIMEOUT": 2010,
|
||||
"INCORRECT_PHONE_COUNTRY_CODE": 2011,
|
||||
"NEW_HANDLE_CONFLICT": 2013,
|
||||
"FAILED_TO_UPDATE": 2014,
|
||||
"FAILED_TO_DELETE": 2015,
|
||||
"FAILED_TO_CREATE": 2016,
|
||||
"INCORRECT_PHONE_NUMBER": 2018,
|
||||
"INSUFFICIENT_MEM_TO_ALLOCATE_CONNECTION": 3001,
|
||||
"PASSWORD_RESET_CODE_GENERATION_PER_EMAIL_TOO_FREQUENTLY": 4000,
|
||||
"TRADE_CREATION_TOO_FREQUENTLY": 4002,
|
||||
"MAP_NOT_UNLOCKED": 4003,
|
||||
|
||||
"GET_SMS_CAPTCHA_RESP_ERROR_CODE": 5003,
|
||||
"NOT_IMPLEMENTED_YET": 65535
|
||||
},
|
||||
"AUTH_CHANNEL": {
|
||||
"SMS": 0,
|
||||
"WECHAT": 1,
|
||||
"WECHAT_GAME": 2
|
||||
},
|
||||
"PLAYER": {
|
||||
"DIAMOND": 1,
|
||||
"GOLD": 2,
|
||||
"ENERGY": 3,
|
||||
"SMS_EXPIRED_SECONDS":120,
|
||||
"SMS_VALID_RESEND_PERIOD_SECONDS":30,
|
||||
"INT_AUTH_TOKEN_TTL_SECONDS":604800
|
||||
},
|
||||
"WS": {
|
||||
"INTERVAL_TO_PING": 2000,
|
||||
"WILL_KICK_IF_INACTIVE_FOR": 6000
|
||||
}
|
||||
}
|
38
battle_srv/common/constants_loader.go
Normal file
38
battle_srv/common/constants_loader.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/imdario/mergo"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// 隐式导入
|
||||
var Constants *constants
|
||||
|
||||
func MustParseConstants() {
|
||||
fp := filepath.Join(Conf.General.AppRoot, "common/constants.json")
|
||||
if isNotExist(fp) {
|
||||
Logger.Fatal("common/constants.json文件不存在")
|
||||
}
|
||||
Constants = new(constants)
|
||||
loadJSON(fp, Constants)
|
||||
|
||||
Logger.Debug("Conf.General.ServerEnv", zap.String("env", Conf.General.ServerEnv))
|
||||
if Conf.General.ServerEnv == SERVER_ENV_TEST {
|
||||
fp = filepath.Join(Conf.General.AppRoot, "common/constants_test.json")
|
||||
if !isNotExist(fp) {
|
||||
testConstants := new(constants)
|
||||
loadJSON(fp, testConstants)
|
||||
//Logger.Debug(spew.Sdump(Constants))
|
||||
//Logger.Debug(spew.Sdump(testConstants))
|
||||
err := mergo.Merge(testConstants, Constants)
|
||||
ErrFatal(err)
|
||||
Constants = testConstants
|
||||
//Logger.Debug("mergo.Merge", zap.Error(err))
|
||||
//Logger.Debug(spew.Sdump(testConstants))
|
||||
}
|
||||
}
|
||||
constantsPost()
|
||||
// Logger.Debug("const", zap.Int("IntAuthTokenTTLSeconds", Constants.Player.IntAuthTokenTTLSeconds))
|
||||
}
|
64
battle_srv/common/constants_struct.go
Normal file
64
battle_srv/common/constants_struct.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package common
|
||||
|
||||
type constants struct {
|
||||
AuthChannel struct {
|
||||
Sms int `json:"SMS"`
|
||||
Wechat int `json:"WECHAT"`
|
||||
WechatGame int `json:"WECHAT_GAME"`
|
||||
} `json:"AUTH_CHANNEL"`
|
||||
Player struct {
|
||||
Diamond int `json:"DIAMOND"`
|
||||
Energy int `json:"ENERGY"`
|
||||
Gold int `json:"GOLD"`
|
||||
IntAuthTokenTTLSeconds int `json:"INT_AUTH_TOKEN_TTL_SECONDS"`
|
||||
SmsExpiredSeconds int `json:"SMS_EXPIRED_SECONDS"`
|
||||
SmsValidResendPeriodSeconds int `json:"SMS_VALID_RESEND_PERIOD_SECONDS"`
|
||||
} `json:"PLAYER"`
|
||||
RetCode struct {
|
||||
Duplicated int `json:"DUPLICATED"`
|
||||
FailedToCreate int `json:"FAILED_TO_CREATE"`
|
||||
FailedToDelete int `json:"FAILED_TO_DELETE"`
|
||||
FailedToUpdate int `json:"FAILED_TO_UPDATE"`
|
||||
IncorrectCaptcha int `json:"INCORRECT_CAPTCHA"`
|
||||
IncorrectHandle int `json:"INCORRECT_HANDLE"`
|
||||
IncorrectPassword int `json:"INCORRECT_PASSWORD"`
|
||||
IncorrectPhoneCountryCode int `json:"INCORRECT_PHONE_COUNTRY_CODE"`
|
||||
IncorrectPhoneNumber int `json:"INCORRECT_PHONE_NUMBER"`
|
||||
InsufficientMemToAllocateConnection int `json:"INSUFFICIENT_MEM_TO_ALLOCATE_CONNECTION"`
|
||||
InvalidEmailLiteral int `json:"INVALID_EMAIL_LITERAL"`
|
||||
InvalidRequestParam int `json:"INVALID_REQUEST_PARAM"`
|
||||
InvalidToken int `json:"INVALID_TOKEN"`
|
||||
IsTestAcc int `json:"IS_TEST_ACC"`
|
||||
IsBotAcc int `json:"IS_BOT_ACC"`
|
||||
LackOfDiamond int `json:"LACK_OF_DIAMOND"`
|
||||
LackOfEnergy int `json:"LACK_OF_ENERGY"`
|
||||
LackOfGold int `json:"LACK_OF_GOLD"`
|
||||
MapNotUnlocked int `json:"MAP_NOT_UNLOCKED"`
|
||||
MysqlError int `json:"MYSQL_ERROR"`
|
||||
GetSmsCaptchaRespErrorCode int `json:"GET_SMS_CAPTCHA_RESP_ERROR_CODE"`
|
||||
NewHandleConflict int `json:"NEW_HANDLE_CONFLICT"`
|
||||
NonexistentAct int `json:"NONEXISTENT_ACT"`
|
||||
NonexistentActHandler int `json:"NONEXISTENT_ACT_HANDLER"`
|
||||
LocallyNoAvailableRoom int `json:"LOCALLY_NO_AVAILABLE_ROOM"`
|
||||
LocallyNoSpecifiedRoom int `json:"LOCALLY_NO_SPECIFIED_ROOM"`
|
||||
PlayerNotAddableToRoom int `json:"PLAYER_NOT_ADDABLE_TO_ROOM"`
|
||||
PlayerNotReAddableToRoom int `json:"PLAYER_NOT_READDABLE_TO_ROOM"`
|
||||
PlayerNotFound int `json:"PLAYER_NOT_FOUND"`
|
||||
PlayerCheating int `json:"PLAYER_CHEATING"`
|
||||
NotImplementedYet int `json:"NOT_IMPLEMENTED_YET"`
|
||||
NoAssociatedEmail int `json:"NO_ASSOCIATED_EMAIL"`
|
||||
Ok int `json:"OK"`
|
||||
PasswordResetCodeGenerationPerEmailTooFrequently int `json:"PASSWORD_RESET_CODE_GENERATION_PER_EMAIL_TOO_FREQUENTLY"`
|
||||
SendEmailTimeout int `json:"SEND_EMAIL_TIMEOUT"`
|
||||
SmsCaptchaNotMatch int `json:"SMS_CAPTCHA_NOT_MATCH"`
|
||||
SmsCaptchaRequestedTooFrequently int `json:"SMS_CAPTCHA_REQUESTED_TOO_FREQUENTLY"`
|
||||
TradeCreationTooFrequently int `json:"TRADE_CREATION_TOO_FREQUENTLY"`
|
||||
UnknownError int `json:"UNKNOWN_ERROR"`
|
||||
WechatServerError int `json:"WECHAT_SERVER_ERROR"`
|
||||
Comment string `json:"__comment__"`
|
||||
} `json:"RET_CODE"`
|
||||
Ws struct {
|
||||
IntervalToPing int `json:"INTERVAL_TO_PING"`
|
||||
WillKickIfInactiveFor int `json:"WILL_KICK_IF_INACTIVE_FOR"`
|
||||
} `json:"WS"`
|
||||
}
|
7
battle_srv/common/constants_test.json
Normal file
7
battle_srv/common/constants_test.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"PLAYER": {
|
||||
"SMS_EXPIRED_SECONDS":30,
|
||||
"SMS_VALID_RESEND_PERIOD_SECONDS":8,
|
||||
"INT_AUTH_TOKEN_TTL_SECONDS":1800
|
||||
}
|
||||
}
|
23
battle_srv/common/logger.go
Normal file
23
battle_srv/common/logger.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
var Logger *zap.Logger
|
||||
var LoggerConfig zap.Config
|
||||
|
||||
func init() {
|
||||
LoggerConfig = zap.NewDevelopmentConfig()
|
||||
LoggerConfig.Level.SetLevel(zap.InfoLevel)
|
||||
LoggerConfig.Development = false
|
||||
LoggerConfig.Sampling = &zap.SamplingConfig{
|
||||
Initial: 100,
|
||||
Thereafter: 100,
|
||||
}
|
||||
LoggerConfig.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
|
||||
var err error
|
||||
Logger, err = LoggerConfig.Build()
|
||||
ErrFatal(err)
|
||||
}
|
35
battle_srv/common/utils/rand.go
Normal file
35
battle_srv/common/utils/rand.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
crypto_rand "crypto/rand"
|
||||
"encoding/hex"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
var Rand *privateRand
|
||||
|
||||
type privateRand struct {
|
||||
*rand.Rand
|
||||
}
|
||||
|
||||
func init() {
|
||||
Rand = &privateRand{rand.New(rand.NewSource(time.Now().UnixNano()))}
|
||||
}
|
||||
|
||||
func (p *privateRand) Number(numberRange ...int) int {
|
||||
nr := 0
|
||||
if len(numberRange) > 1 {
|
||||
nr = 1
|
||||
nr = p.Intn(numberRange[1]-numberRange[0]) + numberRange[0]
|
||||
} else {
|
||||
nr = p.Intn(numberRange[0])
|
||||
}
|
||||
return nr
|
||||
}
|
||||
|
||||
func TokenGenerator(len int) string {
|
||||
b := make([]byte, len/2)
|
||||
crypto_rand.Read(b)
|
||||
return hex.EncodeToString(b)
|
||||
}
|
19
battle_srv/common/utils/time.go
Normal file
19
battle_srv/common/utils/time.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package utils
|
||||
|
||||
import "time"
|
||||
|
||||
func UnixtimeNano() int64 {
|
||||
return time.Now().UnixNano()
|
||||
}
|
||||
|
||||
func UnixtimeMicro() int64 {
|
||||
return time.Now().UnixNano() / 1000
|
||||
}
|
||||
|
||||
func UnixtimeMilli() int64 {
|
||||
return time.Now().UnixNano() / 1000000
|
||||
}
|
||||
|
||||
func UnixtimeSec() int64 {
|
||||
return time.Now().Unix()
|
||||
}
|
283
battle_srv/common/utils/wechat.go
Normal file
283
battle_srv/common/utils/wechat.go
Normal file
@@ -0,0 +1,283 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha1"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"go.uber.org/zap"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
. "server/common"
|
||||
. "server/configs"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
var WechatIns *wechat
|
||||
var WechatGameIns *wechat
|
||||
|
||||
func InitWechat(conf WechatConfig) {
|
||||
WechatIns = NewWechatIns(&conf, Constants.AuthChannel.Wechat)
|
||||
}
|
||||
|
||||
func InitWechatGame(conf WechatConfig) {
|
||||
WechatGameIns = NewWechatIns(&conf, Constants.AuthChannel.WechatGame)
|
||||
}
|
||||
|
||||
func NewWechatIns(conf *WechatConfig, channel int) *wechat {
|
||||
newWechat := &wechat{
|
||||
config: conf,
|
||||
channel: channel,
|
||||
}
|
||||
return newWechat
|
||||
}
|
||||
|
||||
const ()
|
||||
|
||||
type wechat struct {
|
||||
config *WechatConfig
|
||||
channel int
|
||||
}
|
||||
|
||||
// CommonError 微信返回的通用错误json
|
||||
type CommonError struct {
|
||||
ErrCode int64 `json:"errcode"`
|
||||
ErrMsg string `json:"errmsg"`
|
||||
}
|
||||
|
||||
// ResAccessToken 获取用户授权access_token的返回结果
|
||||
type resAccessToken struct {
|
||||
CommonError
|
||||
|
||||
AccessToken string `json:"access_token"`
|
||||
ExpiresIn int64 `json:"expires_in"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
OpenID string `json:"openid"`
|
||||
Scope string `json:"scope"`
|
||||
}
|
||||
|
||||
// Config 返回给用户jssdk配置信息
|
||||
type JsConfig struct {
|
||||
AppID string `json:"app_id"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
NonceStr string `json:"nonce_str"`
|
||||
Signature string `json:"signature"`
|
||||
}
|
||||
|
||||
// resTicket 请求jsapi_tikcet返回结果
|
||||
type resTicket struct {
|
||||
CommonError
|
||||
|
||||
Ticket string `json:"ticket"`
|
||||
ExpiresIn int64 `json:"expires_in"`
|
||||
}
|
||||
|
||||
func (w *wechat) GetJsConfig(uri string) (config *JsConfig, err error) {
|
||||
config = new(JsConfig)
|
||||
var ticketStr string
|
||||
ticketStr, err = w.getTicket()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
nonceStr := randomStr(16)
|
||||
timestamp := UnixtimeSec()
|
||||
str := fmt.Sprintf("jsapi_ticket=%s&noncestr=%s×tamp=%d&url=%s", ticketStr, nonceStr, timestamp, uri)
|
||||
sigStr := signature(str)
|
||||
|
||||
config.AppID = w.config.AppID
|
||||
config.NonceStr = nonceStr
|
||||
config.Timestamp = timestamp
|
||||
config.Signature = sigStr
|
||||
return
|
||||
}
|
||||
|
||||
//TODO add cache, getTicket 获取jsapi_ticket
|
||||
func (w *wechat) getTicket() (ticketStr string, err error) {
|
||||
var ticket resTicket
|
||||
ticket, err = w.getTicketFromServer()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ticketStr = ticket.Ticket
|
||||
return
|
||||
}
|
||||
|
||||
func (w *wechat) GetOauth2Basic(authcode string) (result resAccessToken, err error) {
|
||||
var accessTokenURL string
|
||||
if w.channel == Constants.AuthChannel.WechatGame {
|
||||
accessTokenURL = w.config.ApiProtocol + "://" + w.config.ApiGateway + "/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"
|
||||
}
|
||||
if w.channel == Constants.AuthChannel.Wechat {
|
||||
accessTokenURL = w.config.ApiProtocol + "://" + w.config.ApiGateway + "/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"
|
||||
}
|
||||
urlStr := fmt.Sprintf(accessTokenURL, w.config.AppID, w.config.AppSecret, authcode)
|
||||
Logger.Info("urlStr", zap.Any(":", urlStr))
|
||||
response, err := get(urlStr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal(response, &result)
|
||||
if err != nil {
|
||||
Logger.Info("GetOauth2Basic marshal error", zap.Any("err", err))
|
||||
return
|
||||
}
|
||||
if result.ErrCode != 0 {
|
||||
err = fmt.Errorf("GetOauth2Basic error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//UserInfo 用户授权获取到用户信息
|
||||
type UserInfo struct {
|
||||
CommonError
|
||||
OpenID string `json:"openid"`
|
||||
Nickname string `json:"nickname"`
|
||||
Sex int32 `json:"sex"`
|
||||
Province string `json:"province"`
|
||||
City string `json:"city"`
|
||||
Country string `json:"country"`
|
||||
HeadImgURL string `json:"headimgurl"`
|
||||
Privilege []string `json:"privilege"`
|
||||
Unionid string `json:"unionid"`
|
||||
}
|
||||
|
||||
func (w *wechat) GetMoreInfo(accessToken string, openId string) (result UserInfo, err error) {
|
||||
userInfoURL := w.config.ApiProtocol + "://" + w.config.ApiGateway + "/sns/userinfo?appid=%s&access_token=%s&openid=%s&lang=zh_CN"
|
||||
urlStr := fmt.Sprintf(userInfoURL, w.config.AppID, accessToken, openId)
|
||||
response, err := get(urlStr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal(response, &result)
|
||||
if err != nil {
|
||||
Logger.Info("GetMoreInfo marshal error", zap.Any("err", err))
|
||||
return
|
||||
}
|
||||
if result.ErrCode != 0 {
|
||||
err = fmt.Errorf("GetMoreInfo error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//HTTPGet get 请求
|
||||
func get(uri string) ([]byte, error) {
|
||||
response, err := http.Get(uri)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer response.Body.Close()
|
||||
if response.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("http get error : uri=%v , statusCode=%v", uri, response.StatusCode)
|
||||
}
|
||||
body, err := ioutil.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return body, err
|
||||
}
|
||||
|
||||
//PostJSON post json 数据请求
|
||||
func post(uri string, obj interface{}) ([]byte, error) {
|
||||
jsonData, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
jsonData = bytes.Replace(jsonData, []byte("\\u003c"), []byte("<"), -1)
|
||||
jsonData = bytes.Replace(jsonData, []byte("\\u003e"), []byte(">"), -1)
|
||||
jsonData = bytes.Replace(jsonData, []byte("\\u0026"), []byte("&"), -1)
|
||||
|
||||
body := bytes.NewBuffer(jsonData)
|
||||
response, err := http.Post(uri, "application/json;charset=utf-8", body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
if response.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("http get error : uri=%v , statusCode=%v", uri, response.StatusCode)
|
||||
}
|
||||
return ioutil.ReadAll(response.Body)
|
||||
}
|
||||
|
||||
//Signature sha1签名
|
||||
func signature(params ...string) string {
|
||||
sort.Strings(params)
|
||||
h := sha1.New()
|
||||
for _, s := range params {
|
||||
io.WriteString(h, s)
|
||||
}
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
||||
|
||||
//RandomStr 随机生成字符串
|
||||
func randomStr(length int) string {
|
||||
str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
bytes := []byte(str)
|
||||
result := []byte{}
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
for i := 0; i < length; i++ {
|
||||
result = append(result, bytes[r.Intn(len(bytes))])
|
||||
}
|
||||
return string(result)
|
||||
}
|
||||
|
||||
//getTicketFromServer 强制从服务器中获取ticket
|
||||
func (w *wechat) getTicketFromServer() (ticket resTicket, err error) {
|
||||
var accessToken string
|
||||
accessToken, err = w.getAccessTokenFromServer()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
getTicketURL := w.config.ApiProtocol + "://" + w.config.ApiGateway + "/cgi-bin/ticket/getticket?access_token=%s&type=jsapi"
|
||||
var response []byte
|
||||
url := fmt.Sprintf(getTicketURL, accessToken)
|
||||
response, err = get(url)
|
||||
err = json.Unmarshal(response, &ticket)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if ticket.ErrCode != 0 {
|
||||
err = fmt.Errorf("getTicket Error : errcode=%d , errmsg=%s", ticket.ErrCode, ticket.ErrMsg)
|
||||
return
|
||||
}
|
||||
|
||||
//jsAPITicketCacheKey := fmt.Sprintf("jsapi_ticket_%s", w.config.AppID)
|
||||
//expires := ticket.ExpiresIn - 1500
|
||||
//set
|
||||
//err = js.Cache.Set(jsAPITicketCacheKey, ticket.Ticket, time.Duration(expires)*time.Second)
|
||||
return
|
||||
}
|
||||
|
||||
//GetAccessTokenFromServer 强制从微信服务器获取token
|
||||
func (w *wechat) getAccessTokenFromServer() (accessToken string, err error) {
|
||||
AccessTokenURL := w.config.ApiProtocol + "://" + w.config.ApiGateway + "/cgi-bin/token"
|
||||
url := fmt.Sprintf("%s?grant_type=client_credential&appid=%s&secret=%s", AccessTokenURL, w.config.AppID, w.config.AppSecret)
|
||||
var body []byte
|
||||
body, err = get(url)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var r resAccessToken
|
||||
err = json.Unmarshal(body, &r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if r.ErrMsg != "" {
|
||||
err = fmt.Errorf("get access_token error : errcode=%v , errormsg=%v", r.ErrCode, r.ErrMsg)
|
||||
return
|
||||
}
|
||||
|
||||
//accessTokenCacheKey := fmt.Sprintf("access_token_%s", w.config.AppID)
|
||||
//expires := r.ExpiresIn - 1500
|
||||
//set to redis err = ctx.Cache.Set(accessTokenCacheKey, r.AccessToken, time.Duration(expires)*time.Second)
|
||||
accessToken = r.AccessToken
|
||||
return
|
||||
}
|
31
battle_srv/common/vals.go
Normal file
31
battle_srv/common/vals.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
RE_PHONE_NUM = regexp.MustCompile(`^\+?[0-9]{8,14}$`)
|
||||
RE_SMS_CAPTCHA_CODE = regexp.MustCompile(`^[0-9]{4}$`)
|
||||
RE_CHINA_PHONE_NUM = regexp.MustCompile(`^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$`)
|
||||
)
|
||||
|
||||
// 隐式导入
|
||||
var ConstVals = &struct {
|
||||
Player struct {
|
||||
CaptchaExpire time.Duration
|
||||
CaptchaMaxTTL time.Duration
|
||||
}
|
||||
Ws struct {
|
||||
WillKickIfInactiveFor time.Duration
|
||||
}
|
||||
}{}
|
||||
|
||||
func constantsPost() {
|
||||
ConstVals.Player.CaptchaExpire = time.Duration(Constants.Player.SmsExpiredSeconds) * time.Second
|
||||
ConstVals.Player.CaptchaMaxTTL = ConstVals.Player.CaptchaExpire -
|
||||
time.Duration(Constants.Player.SmsValidResendPeriodSeconds)*time.Second
|
||||
|
||||
ConstVals.Ws.WillKickIfInactiveFor = time.Duration(Constants.Ws.WillKickIfInactiveFor) * time.Millisecond
|
||||
}
|
Reference in New Issue
Block a user