Apply .gitignore rules
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
// +build !windows
|
||||
|
||||
package linuxMgr
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
|
||||
"goutil/fileUtil"
|
||||
)
|
||||
|
||||
func init() {
|
||||
//验证文件夹是否存在
|
||||
fileAbsoluteDirectory := filepath.Join("Log")
|
||||
if !fileUtil.IsDirExists(fileAbsoluteDirectory) {
|
||||
if err := os.MkdirAll(fileAbsoluteDirectory, os.ModePerm|os.ModeTemporary); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 标准输出
|
||||
stdoutFile, _ := os.OpenFile("Log/Stdout.txt", os.O_WRONLY|os.O_CREATE|os.O_SYNC, 0644)
|
||||
syscall.Dup2(int(stdoutFile.Fd()), 1)
|
||||
|
||||
// 标准错误输出
|
||||
stderrFile, _ := os.OpenFile("Log/Stderr.txt", os.O_WRONLY|os.O_CREATE|os.O_SYNC|os.O_APPEND, 0644)
|
||||
syscall.Dup2(int(stderrFile.Fd()), 2)
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package managecenterModel
|
||||
|
||||
// 服务器
|
||||
type Server struct {
|
||||
// 服务器Id
|
||||
Id int32 `json:"ServerID"`
|
||||
|
||||
// 服务器名称
|
||||
Name string `json:"ServerName"`
|
||||
|
||||
// 合作商Id
|
||||
PartnerId int32 `json:"PartnerID"`
|
||||
|
||||
// 服务器组Id
|
||||
GroupId int32 `json:"GroupID"`
|
||||
|
||||
// 对应的游戏版本号
|
||||
GameVersionId int32 `json:"GameVersionID"`
|
||||
|
||||
// 需要的最低游戏版本号
|
||||
MinGameVersionId int32 `json:"MinGameVersionID"`
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
package configYaml
|
||||
|
||||
var ConfigYaml = Config{}
|
||||
|
||||
// Config 定义与 YAML 文件结构匹配的结构体
|
||||
type Config struct {
|
||||
Root Root
|
||||
}
|
||||
|
||||
// Root 是整个配置文件的根结构体
|
||||
type Root struct {
|
||||
// 是否是调试模式
|
||||
Debug bool `yaml:"debug"`
|
||||
|
||||
// 是否是 CrossServer 中心节点(标记为 true 时,才会进行排行榜处理)
|
||||
CrossServerCenter bool `yaml:"cross_server_center"`
|
||||
|
||||
// ManagerCenter 配置
|
||||
ManagerCenterConfig ManagerCenterConf `yaml:"manager_center_config"`
|
||||
|
||||
// logmgr 配置
|
||||
LogMgr LogMgr `yaml:"log_mgr"`
|
||||
|
||||
// Web 服务监听地址和端口
|
||||
WebServerAddress string `yaml:"web_server_address"`
|
||||
|
||||
// gRPC 监听地址和端口 (内网地址即可)
|
||||
GrpcServerAddress string `yaml:"grpc_server_address"`
|
||||
|
||||
// 战斗服务器地址
|
||||
FightServerAddress string `yaml:"fight_server_address"`
|
||||
|
||||
// 数据中心地址
|
||||
DataCenterAddress string `yaml:"data_center_address"`
|
||||
|
||||
// OrderId 和 BigGroupId(仅用于非 PlayerServer)
|
||||
OrderId int `yaml:"order_id"`
|
||||
BigGroupId int `yaml:"big_group_id"`
|
||||
|
||||
// 重启时载入 Redis 数据日期范围
|
||||
BaseDay int `yaml:"base_day"`
|
||||
|
||||
// ES 地址
|
||||
EsUrls string `yaml:"es_urls"`
|
||||
|
||||
// 数据库配置
|
||||
DbConfig DBConfig `yaml:"db_config"`
|
||||
|
||||
// 监控相关配置
|
||||
MonitorConfig MonitorConf `yaml:"monitor_config"`
|
||||
|
||||
// 功能开关配置
|
||||
FunctionConfig FunctionConf `yaml:"function_config"`
|
||||
}
|
||||
|
||||
// ManagerCenterConf 是 ManagerCenter 的配置结构体
|
||||
type ManagerCenterConf struct {
|
||||
// ManagerCenter API 的 URL
|
||||
ManageCenterAPIUrl string `yaml:"manage_center_api_url"`
|
||||
|
||||
// 服务器组类型
|
||||
GroupType string `yaml:"group_type"`
|
||||
|
||||
// 刷新间隔,单位:分钟
|
||||
RefreshInterval int `yaml:"refresh_interval"`
|
||||
}
|
||||
|
||||
// LogMgr 是日志管理器的配置结构体
|
||||
type LogMgr struct {
|
||||
// group boxId
|
||||
GroupId string `yaml:"group_id"`
|
||||
|
||||
// group secret
|
||||
GroupSecret string `yaml:"group_secret"`
|
||||
|
||||
// product boxId
|
||||
ProductId string `yaml:"product_id"`
|
||||
}
|
||||
|
||||
// DBConfig 包含数据库和 Redis 的配置
|
||||
type DBConfig struct {
|
||||
|
||||
//管理员数据库配置
|
||||
AdminDB DatabaseConfig `yaml:"admin_db"`
|
||||
|
||||
// 用户数据库配置
|
||||
UserDB DatabaseConfig `yaml:"user_db"`
|
||||
|
||||
// 游戏模型数据库配置
|
||||
GameModel DatabaseConfig `yaml:"game_model"`
|
||||
|
||||
// 游戏数据库配置
|
||||
GameDB DatabaseConfig `yaml:"game_db"`
|
||||
|
||||
// 玩家数据库配置
|
||||
PlayerDB DatabaseConfig `yaml:"player_db"`
|
||||
|
||||
// Redis 配置
|
||||
RedisConfig RedisConfig `yaml:"redis_config"`
|
||||
}
|
||||
|
||||
// DatabaseConfig 是数据库连接的配置结构体
|
||||
type DatabaseConfig struct {
|
||||
// 最大处于开启状态的连接数
|
||||
MaxOpenConns int `yaml:"max_open_conns"`
|
||||
|
||||
// 最大处于空闲状态的连接数
|
||||
MaxIdleConns int `yaml:"max_idle_conns"`
|
||||
|
||||
// 数据库连接字符串
|
||||
ConnectionString string `yaml:"connection_string"`
|
||||
}
|
||||
|
||||
// RedisConfig 是 Redis 连接的配置结构体
|
||||
type RedisConfig struct {
|
||||
// Redis 数据库连接字符串
|
||||
ConnectionString string `yaml:"connection_string"`
|
||||
|
||||
// 密码, 如果要设置用户 Id,则密码设置为: "UserId:Password"
|
||||
Password string `yaml:"password"`
|
||||
|
||||
// 数据库序号
|
||||
Database int `yaml:"database"`
|
||||
|
||||
// 最大活跃连接数
|
||||
MaxActive int `yaml:"max_active"`
|
||||
|
||||
// 最大空闲的连接数
|
||||
MaxIdle int `yaml:"max_idle"`
|
||||
|
||||
// 连接空闲超时时间,单位:秒
|
||||
IdleTimeout int `yaml:"idle_timeout"`
|
||||
|
||||
// 连接超时时间, 单位:秒
|
||||
DialConnectTimeout int `yaml:"dial_connect_timeout"`
|
||||
}
|
||||
|
||||
// MonitorConf 是监控配置的结构体
|
||||
type MonitorConf struct {
|
||||
// 监控使用的服务器 IP (本机的外网地址)
|
||||
ServerIP string `yaml:"server_ip"`
|
||||
|
||||
// 监控使用的服务器名称
|
||||
ServerName string `yaml:"server_name"`
|
||||
|
||||
// 监控的时间间隔(单位:分钟)
|
||||
Interval int `yaml:"interval"`
|
||||
}
|
||||
|
||||
// FunctionConf 是功能开关配置的结构体
|
||||
type FunctionConf struct {
|
||||
// 游戏代码: qyc, xh, dzz
|
||||
GameCode string `yaml:"game_code"`
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"goutil/xmlUtil/gxpath/internal/parse"
|
||||
"goutil/xmlUtil/gxpath/internal/query"
|
||||
"goutil/xmlUtil/gxpath/xpath"
|
||||
)
|
||||
|
||||
type flag int
|
||||
|
||||
const (
|
||||
noneFlag flag = iota
|
||||
filterFlag
|
||||
)
|
||||
|
||||
// builder provides building an XPath expressions.
|
||||
type builder struct {
|
||||
depth int
|
||||
flag flag
|
||||
firstInput query.Query
|
||||
}
|
||||
|
||||
// axisPredicate creates a predicate to predicating for this axis node.
|
||||
func axisPredicate(root *parse.AxisNode) func(xpath.NodeNavigator) bool {
|
||||
// get current axix node type.
|
||||
typ := xpath.ElementNode
|
||||
if root.AxeType == "attribute" {
|
||||
typ = xpath.AttributeNode
|
||||
} else {
|
||||
switch root.Prop {
|
||||
case "comment":
|
||||
typ = xpath.CommentNode
|
||||
case "text":
|
||||
typ = xpath.TextNode
|
||||
// case "processing-instruction":
|
||||
// typ = xpath.ProcessingInstructionNode
|
||||
case "node":
|
||||
typ = xpath.ElementNode
|
||||
}
|
||||
}
|
||||
predicate := func(n xpath.NodeNavigator) bool {
|
||||
if typ == n.NodeType() {
|
||||
if root.LocalName == "" || (root.LocalName == n.LocalName() && root.Prefix == n.Prefix()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
return predicate
|
||||
}
|
||||
|
||||
// processAxisNode buildes a query for the XPath axis node.
|
||||
func (b *builder) processAxisNode(root *parse.AxisNode) (query.Query, error) {
|
||||
var (
|
||||
err error
|
||||
qyInput query.Query
|
||||
qyOutput query.Query
|
||||
predicate = axisPredicate(root)
|
||||
)
|
||||
|
||||
if root.Input == nil {
|
||||
qyInput = &query.ContextQuery{}
|
||||
} else {
|
||||
if b.flag&filterFlag == 0 {
|
||||
if root.AxeType == "child" && (root.Input.Type() == parse.NodeAxis) {
|
||||
if input := root.Input.(*parse.AxisNode); input.AxeType == "descendant-or-self" {
|
||||
var qyGrandInput query.Query
|
||||
if input.Input != nil {
|
||||
qyGrandInput, _ = b.processNode(input.Input)
|
||||
} else {
|
||||
qyGrandInput = &query.ContextQuery{}
|
||||
}
|
||||
qyOutput = &query.DescendantQuery{Input: qyGrandInput, Predicate: predicate, Self: true}
|
||||
return qyOutput, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
qyInput, err = b.processNode(root.Input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
switch root.AxeType {
|
||||
case "ancestor":
|
||||
qyOutput = &query.AncestorQuery{Input: qyInput, Predicate: predicate}
|
||||
case "ancestor-or-self":
|
||||
qyOutput = &query.AncestorQuery{Input: qyInput, Predicate: predicate, Self: true}
|
||||
case "attribute":
|
||||
qyOutput = &query.AttributeQuery{Input: qyInput, Predicate: predicate}
|
||||
case "child":
|
||||
filter := func(n xpath.NodeNavigator) bool {
|
||||
v := predicate(n)
|
||||
switch root.Prop {
|
||||
case "text":
|
||||
v = v && n.NodeType() == xpath.TextNode
|
||||
case "node":
|
||||
v = v && (n.NodeType() == xpath.ElementNode || n.NodeType() == xpath.TextNode)
|
||||
case "comment":
|
||||
v = v && n.NodeType() == xpath.CommentNode
|
||||
}
|
||||
return v
|
||||
}
|
||||
qyOutput = &query.ChildQuery{Input: qyInput, Predicate: filter}
|
||||
case "descendant":
|
||||
qyOutput = &query.DescendantQuery{Input: qyInput, Predicate: predicate}
|
||||
case "descendant-or-self":
|
||||
qyOutput = &query.DescendantQuery{Input: qyInput, Predicate: predicate, Self: true}
|
||||
case "following":
|
||||
qyOutput = &query.FollowingQuery{Input: qyInput, Predicate: predicate}
|
||||
case "following-sibling":
|
||||
qyOutput = &query.FollowingQuery{Input: qyInput, Predicate: predicate, Sibling: true}
|
||||
case "parent":
|
||||
qyOutput = &query.ParentQuery{Input: qyInput, Predicate: predicate}
|
||||
case "preceding":
|
||||
qyOutput = &query.PrecedingQuery{Input: qyInput, Predicate: predicate}
|
||||
case "preceding-sibling":
|
||||
qyOutput = &query.PrecedingQuery{Input: qyInput, Predicate: predicate, Sibling: true}
|
||||
case "self":
|
||||
qyOutput = &query.SelfQuery{Input: qyInput, Predicate: predicate}
|
||||
case "namespace":
|
||||
// haha,what will you do someting??
|
||||
default:
|
||||
err = fmt.Errorf("unknown axe type: %s", root.AxeType)
|
||||
return nil, err
|
||||
}
|
||||
return qyOutput, nil
|
||||
}
|
||||
|
||||
// processFilterNode builds query.Query for the XPath filter predicate.
|
||||
func (b *builder) processFilterNode(root *parse.FilterNode) (query.Query, error) {
|
||||
b.flag |= filterFlag
|
||||
|
||||
qyInput, err := b.processNode(root.Input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
qyCond, err := b.processNode(root.Condition)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
qyOutput := &query.FilterQuery{Input: qyInput, Predicate: qyCond}
|
||||
return qyOutput, nil
|
||||
}
|
||||
|
||||
// processFunctionNode buildes query.Query for the XPath function node.
|
||||
func (b *builder) processFunctionNode(root *parse.FunctionNode) (query.Query, error) {
|
||||
var qyOutput query.Query
|
||||
switch root.FuncName {
|
||||
case "starts-with":
|
||||
arg1, err := b.processNode(root.Args[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
arg2, err := b.processNode(root.Args[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
startwith := &startwithFunc{arg1, arg2}
|
||||
qyOutput = &query.XPathFunction{Input: b.firstInput, Func: startwith.do}
|
||||
case "substring":
|
||||
//substring( string , start [, length] )
|
||||
if len(root.Args) < 2 {
|
||||
return nil, errors.New("xpath: substring function must have at least two parameter")
|
||||
}
|
||||
var (
|
||||
arg1, arg2, arg3 query.Query
|
||||
err error
|
||||
)
|
||||
if arg1, err = b.processNode(root.Args[0]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if arg2, err = b.processNode(root.Args[1]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(root.Args) == 3 {
|
||||
if arg3, err = b.processNode(root.Args[2]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
substring := &substringFunc{arg1, arg2, arg3}
|
||||
qyOutput = &query.XPathFunction{Input: b.firstInput, Func: substring.do}
|
||||
case "normalize-space":
|
||||
if len(root.Args) == 0 {
|
||||
return nil, errors.New("xpath: normalize-space function must have at least one parameter")
|
||||
}
|
||||
argQuery, err := b.processNode(root.Args[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
qyOutput = &query.XPathFunction{Input: argQuery, Func: normalizespaceFunc}
|
||||
case "name":
|
||||
qyOutput = &query.XPathFunction{Input: b.firstInput, Func: nameFunc}
|
||||
case "last":
|
||||
qyOutput = &query.XPathFunction{Input: b.firstInput, Func: lastFunc}
|
||||
case "position":
|
||||
qyOutput = &query.XPathFunction{Input: b.firstInput, Func: positionFunc}
|
||||
case "count":
|
||||
if b.firstInput == nil {
|
||||
return nil, errors.New("xpath: expression must evaluate to node-set")
|
||||
}
|
||||
if len(root.Args) == 0 {
|
||||
return nil, fmt.Errorf("xpath: count(node-sets) function must with have parameters node-sets")
|
||||
}
|
||||
argQuery, err := b.processNode(root.Args[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
qyOutput = &query.XPathFunction{Input: argQuery, Func: countFunc}
|
||||
default:
|
||||
return nil, fmt.Errorf("not yet support this function %s()", root.FuncName)
|
||||
}
|
||||
return qyOutput, nil
|
||||
}
|
||||
|
||||
func (b *builder) processOperatorNode(root *parse.OperatorNode) (query.Query, error) {
|
||||
left, err := b.processNode(root.Left)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
right, err := b.processNode(root.Right)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var qyOutput query.Query
|
||||
switch root.Op {
|
||||
case "+", "-", "div", "mod": // Numeric operator
|
||||
var exprFunc func(interface{}, interface{}) interface{}
|
||||
switch root.Op {
|
||||
case "+":
|
||||
exprFunc = plusFunc
|
||||
case "-":
|
||||
exprFunc = minusFunc
|
||||
case "div":
|
||||
exprFunc = divFunc
|
||||
case "mod":
|
||||
exprFunc = modFunc
|
||||
}
|
||||
qyOutput = &query.NumericExpr{Left: left, Right: right, Do: exprFunc}
|
||||
case "=", ">", ">=", "<", "<=", "!=":
|
||||
var exprFunc func(query.Iterator, interface{}, interface{}) interface{}
|
||||
switch root.Op {
|
||||
case "=":
|
||||
exprFunc = eqFunc
|
||||
case ">":
|
||||
exprFunc = gtFunc
|
||||
case ">=":
|
||||
exprFunc = geFunc
|
||||
case "<":
|
||||
exprFunc = ltFunc
|
||||
case "<=":
|
||||
exprFunc = leFunc
|
||||
case "!=":
|
||||
exprFunc = neFunc
|
||||
}
|
||||
qyOutput = &query.LogicalExpr{Left: left, Right: right, Do: exprFunc}
|
||||
case "or", "and", "|":
|
||||
isOr := false
|
||||
if root.Op == "or" || root.Op == "|" {
|
||||
isOr = true
|
||||
}
|
||||
qyOutput = &query.BooleanExpr{Left: left, Right: right, IsOr: isOr}
|
||||
}
|
||||
return qyOutput, nil
|
||||
}
|
||||
|
||||
func (b *builder) processNode(root parse.Node) (q query.Query, err error) {
|
||||
if b.depth = b.depth + 1; b.depth > 1024 {
|
||||
err = errors.New("the xpath expressions is too complex")
|
||||
return
|
||||
}
|
||||
|
||||
switch root.Type() {
|
||||
case parse.NodeConstantOperand:
|
||||
n := root.(*parse.OperandNode)
|
||||
q = &query.XPathConstant{Val: n.Val}
|
||||
case parse.NodeRoot:
|
||||
q = &query.ContextQuery{Root: true}
|
||||
case parse.NodeAxis:
|
||||
q, err = b.processAxisNode(root.(*parse.AxisNode))
|
||||
b.firstInput = q
|
||||
case parse.NodeFilter:
|
||||
q, err = b.processFilterNode(root.(*parse.FilterNode))
|
||||
case parse.NodeFunction:
|
||||
q, err = b.processFunctionNode(root.(*parse.FunctionNode))
|
||||
case parse.NodeOperator:
|
||||
q, err = b.processOperatorNode(root.(*parse.OperatorNode))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Build builds a specified XPath expressions expr.
|
||||
func Build(expr string) (query.Query, error) {
|
||||
root := parse.Parse(expr)
|
||||
b := &builder{}
|
||||
return b.processNode(root)
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package mysqlUtil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConvertConnectionStringFromCSharpToGo(t *testing.T) {
|
||||
csharp := "DataSource=10.66.195.134;port=3306;UserId=admin;Password=MOQIkaka$#@!1234;Database=s9501_sd_log;Allow Zero Datetime=true;charset=utf8;pooling=false;command timeout=60;AllowUserVariables=True;"
|
||||
expected := "admin:MOQIkaka$#@!1234@tcp(10.66.195.134:3306)/s9501_sd_log?charset=utf8&parseTime=true&loc=Local&timeout=60s||MaxOpenConns=0||MaxIdleConns=0"
|
||||
|
||||
if goConn := ConvertConnectionStringFromCSharpToGo(csharp); goConn != expected {
|
||||
t.Errorf("Expected %s, but got %s", expected, goConn)
|
||||
}
|
||||
|
||||
// csharp = "DataSource=10.162.2.205;port=3306;UserId=admin;Password=MOQIkaka$#@!1234;Database=s201_dzz_log;Allow Zero Datetime=true;charset=utf8;pooling=false;min pool size=20;max pool size=200;command timeout=60;AllowUserVariables=True;"
|
||||
// expected = "admin:MOQIkaka$#@!1234@tcp(10.162.2.205:3306)/s201_dzz_log?charset=utf8&parseTime=true&loc=Local&timeout=60s||MaxOpenConns=0||MaxIdleConns=0"
|
||||
|
||||
// if goConn := ConvertConnectionStringFromCSharpToGo(csharp); goConn != expected {
|
||||
// t.Errorf("Expected %s, but got %s", expected, goConn)
|
||||
// }
|
||||
}
|
||||
|
||||
func TestIsCSharpStyle(t *testing.T) {
|
||||
connString := "DataSource=10.66.195.134;port=3306;UserId=admin;Password=MOQIkaka$#@!1234;Database=s9501_sd_log;Allow Zero Datetime=true;charset=utf8;pooling=false;command timeout=60;AllowUserVariables=True;"
|
||||
if !IsCSharpStyle(connString) {
|
||||
t.Errorf("it's should be C# style, but now not")
|
||||
}
|
||||
|
||||
connString = "admin:MOQIkaka$#@!1234@tcp(10.66.195.134:3306)/s9501_sd_log?charset=utf8&parseTime=true&loc=Local&timeout=60s||MaxOpenConns=0||MaxIdleConns=0"
|
||||
if IsCSharpStyle(connString) {
|
||||
t.Errorf("it's should not be C# style, but now it is")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsGoStyle(t *testing.T) {
|
||||
connString := "admin:MOQIkaka$#@!1234@tcp(10.66.195.134:3306)/s9501_sd_log?charset=utf8&parseTime=true&loc=Local&timeout=60s||MaxOpenConns=0||MaxIdleConns=0"
|
||||
if !IsGoStyle(connString) {
|
||||
t.Errorf("it's should be Go style, but now not")
|
||||
}
|
||||
|
||||
connString = "DataSource=10.66.195.134;port=3306;UserId=admin;Password=MOQIkaka$#@!1234;Database=s9501_sd_log;Allow Zero Datetime=true;charset=utf8;pooling=false;command timeout=60;AllowUserVariables=True;"
|
||||
if IsGoStyle(connString) {
|
||||
t.Errorf("it's should not be Go style, but now it is")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user