更新代码
This commit is contained in:
parent
e780ed1f5b
commit
553426e0d6
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@
|
||||
/Goleaf
|
||||
Goleaf.tar
|
||||
source/main
|
||||
playbook/node_modules/*
|
||||
|
||||
15
kafka/.vscode/launch.json
vendored
Normal file
15
kafka/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
// 使用 IntelliSense 了解相关属性。
|
||||
// 悬停以查看现有属性的描述。
|
||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch file",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "debug",
|
||||
"program": "${file}"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
kafka/__debug_bin3625240056.exe
Normal file
BIN
kafka/__debug_bin3625240056.exe
Normal file
Binary file not shown.
14
kafka/conf/conf.yml
Normal file
14
kafka/conf/conf.yml
Normal file
@ -0,0 +1,14 @@
|
||||
db:
|
||||
host: "localhost"
|
||||
user: root
|
||||
password: "hef0YMId4DayV0XuGCLmjNjEAVg="
|
||||
port: 3306
|
||||
games:
|
||||
- name: "Merge_Pet_Local"
|
||||
topic: "Merge_Pet_Local"
|
||||
partition: 0
|
||||
db_name: "Merge_Pet_Local"
|
||||
- name: "Merge_Pet_Test"
|
||||
topic: "Merge_Pet_Test"
|
||||
partition: 0
|
||||
db_name: "Merge_Pet_Test"
|
||||
98
kafka/config/config.go
Normal file
98
kafka/config/config.go
Normal file
@ -0,0 +1,98 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
DB struct {
|
||||
Host string `yaml:"host"`
|
||||
User string `yaml:"user"`
|
||||
Password string `yaml:"password"`
|
||||
Port int `yaml:"port"`
|
||||
} `yaml:"db"`
|
||||
Games []struct {
|
||||
Name string `yaml:"name"`
|
||||
DBName string `yaml:"db_name"`
|
||||
Topic string `yaml:"topic"`
|
||||
Partition int `yaml:"partition"`
|
||||
} `yaml:"games"`
|
||||
}
|
||||
|
||||
type Game struct {
|
||||
Name string
|
||||
DBName string
|
||||
Topic string
|
||||
Partition int
|
||||
}
|
||||
|
||||
type DBConf struct {
|
||||
Host string
|
||||
User string
|
||||
Password string
|
||||
Port int
|
||||
DbNamee string
|
||||
}
|
||||
|
||||
var Conf *Config
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
Conf, err = loadConfig("./conf/conf.yml")
|
||||
if err != nil {
|
||||
log.Fatalf("Error loading config: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func loadConfig(filename string) (*Config, error) {
|
||||
absPath, err := filepath.Abs(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fmt.Println(absPath)
|
||||
data, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var config Config
|
||||
err = yaml.Unmarshal(data, &config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
func GetDbConfig(Key string) *DBConf {
|
||||
DBConf := &DBConf{}
|
||||
for _, game := range Conf.Games {
|
||||
if game.Name == Key {
|
||||
DBConf.Host = Conf.DB.Host
|
||||
DBConf.User = Conf.DB.User
|
||||
DBConf.Password = Conf.DB.Password
|
||||
DBConf.Port = Conf.DB.Port
|
||||
DBConf.DbNamee = game.DBName
|
||||
break
|
||||
}
|
||||
}
|
||||
return DBConf
|
||||
}
|
||||
|
||||
func GetGames() []*Game {
|
||||
games := make([]*Game, 0)
|
||||
for _, game := range Conf.Games {
|
||||
games = append(games, &Game{
|
||||
Name: game.Name,
|
||||
DBName: game.DBName,
|
||||
Topic: game.Topic,
|
||||
Partition: game.Partition,
|
||||
})
|
||||
}
|
||||
return games
|
||||
}
|
||||
94
kafka/db/db.go
Normal file
94
kafka/db/db.go
Normal file
@ -0,0 +1,94 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"kafka-comsumer/config"
|
||||
"kafka-comsumer/util"
|
||||
"strconv"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/segmentio/kafka-go"
|
||||
)
|
||||
|
||||
var Container = map[string]*sqlx.DB{}
|
||||
|
||||
func GetContainer(Key string) *sqlx.DB {
|
||||
v, ok := Container[Key]
|
||||
if !ok {
|
||||
DbConf := config.GetDbConfig(Key)
|
||||
NewDbPass, _ := util.Decrypt(DbConf.Password, util.SECRET_KEY)
|
||||
db, err := sqlx.Connect("mysql", DbConf.User+":"+NewDbPass+"@tcp("+DbConf.Host+":"+strconv.Itoa(DbConf.Port)+")/"+DbConf.DbNamee)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
Container[Key] = db
|
||||
return db
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func ProcessMsg(SqlDb *sqlx.DB, m kafka.Message) error {
|
||||
if SqlDb == nil {
|
||||
return nil
|
||||
}
|
||||
// fmt.Printf("Message at offset %d: %s = %s\n", m.Offset, string(m.Key), string(m.Value))
|
||||
tx := SqlDb.MustBegin()
|
||||
var err error
|
||||
switch string(m.Key) {
|
||||
case "Login_log":
|
||||
err = login(SqlDb, m)
|
||||
case "Login_Out":
|
||||
err = login(SqlDb, m)
|
||||
default:
|
||||
err = event(SqlDb, m)
|
||||
}
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
offset(SqlDb, m)
|
||||
tx.Commit()
|
||||
// fmt.Println("msg process success")
|
||||
return nil
|
||||
}
|
||||
|
||||
func login(SqlDb *sqlx.DB, m kafka.Message) error {
|
||||
var V map[string]interface{}
|
||||
json.Unmarshal(m.Value, &V)
|
||||
sql := "INSERT INTO log_login (`Uid`, `Event`, `Timestamp`) VALUES (?, ?, ?)"
|
||||
|
||||
_, err := SqlDb.Exec(sql, V["Uid"], m.Key, V["TimeStamp"])
|
||||
return err
|
||||
}
|
||||
|
||||
func event(SqlDb *sqlx.DB, m kafka.Message) error {
|
||||
var V map[string]interface{}
|
||||
json.Unmarshal(m.Value, &V)
|
||||
Param, err := json.Marshal(V["Param"])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sql := "INSERT INTO log_event (`Uid`, `Event`, `Param`, `Timestamp`) VALUES (?, ?, ?, ?)"
|
||||
_, err = SqlDb.Exec(sql, V["Uid"], m.Key, string(Param), V["TimeStamp"])
|
||||
return err
|
||||
}
|
||||
|
||||
func offset(SqlDb *sqlx.DB, m kafka.Message) error {
|
||||
sql := " INSERT INTO `log_var` (`Key` , `Value`, `Timestamp`) Values (?,?,?) ON DUPLICATE KEY UPDATE `key` = ? , `Value` = ? ,`Timestamp`=?"
|
||||
Value := strconv.FormatInt(m.Offset+1, 10)
|
||||
Timestamp := util.GetNowTime()
|
||||
_, err := SqlDb.Exec(sql, "offset", Value, Timestamp, "offset", Value, Timestamp)
|
||||
return err
|
||||
}
|
||||
|
||||
func GetOffset(SqlDb *sqlx.DB) int64 {
|
||||
sql := "select `Value` from `log_var` where `Key` = 'offset'"
|
||||
var offset string
|
||||
err := SqlDb.Get(&offset, sql)
|
||||
if offset == "" || err != nil {
|
||||
return kafka.FirstOffset
|
||||
}
|
||||
v, _ := strconv.ParseInt(offset, 10, 64)
|
||||
return v
|
||||
}
|
||||
17
kafka/go.mod
Normal file
17
kafka/go.mod
Normal file
@ -0,0 +1,17 @@
|
||||
module kafka-comsumer
|
||||
|
||||
go 1.23.1
|
||||
|
||||
require github.com/segmentio/kafka-go v0.4.47
|
||||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||
github.com/jmoiron/sqlx v1.4.0 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.21 // indirect
|
||||
github.com/stretchr/testify v1.9.0 // indirect
|
||||
golang.org/x/net v0.28.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
83
kafka/go.sum
Normal file
83
kafka/go.sum
Normal file
@ -0,0 +1,83 @@
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
|
||||
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
|
||||
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/segmentio/kafka-go v0.4.47 h1:IqziR4pA3vrZq7YdRxaT3w1/5fvIH5qpCwstUanQQB0=
|
||||
github.com/segmentio/kafka-go v0.4.47/go.mod h1:HjF6XbOKh0Pjlkr5GVZxt6CsjjwnmhVOfURM5KMd8qg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
BIN
kafka/kafka-comsumer.tar
Normal file
BIN
kafka/kafka-comsumer.tar
Normal file
Binary file not shown.
78
kafka/main.go
Normal file
78
kafka/main.go
Normal file
@ -0,0 +1,78 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"kafka-comsumer/config"
|
||||
"kafka-comsumer/db"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"github.com/segmentio/kafka-go"
|
||||
)
|
||||
|
||||
var (
|
||||
WorkChan = make(chan *kafka.Message, 100)
|
||||
Wait sync.WaitGroup
|
||||
)
|
||||
|
||||
// GOOS=linux GOARCH=amd64 go build -o /data/pet_home_devops/kafka/release/kafka_comsumer main.go
|
||||
|
||||
func main() {
|
||||
// 打开日志文件
|
||||
logFile, err := os.OpenFile("./log/kafka-comsumer.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to open log file: %v", err)
|
||||
}
|
||||
defer logFile.Close()
|
||||
|
||||
// 将日志输出重定向到文件
|
||||
log.SetOutput(logFile)
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
Games := config.GetGames()
|
||||
for _, game := range Games {
|
||||
go comsumer(game)
|
||||
}
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL)
|
||||
sig := <-c
|
||||
log.Printf("kafka comsumer closing down (signal: %v)\n", sig.String())
|
||||
Wait.Wait()
|
||||
}
|
||||
|
||||
func comsumer(Game *config.Game) {
|
||||
sqlDb := db.GetContainer(Game.Name)
|
||||
if sqlDb == nil {
|
||||
log.Printf("comsumer db %s not exist \n", Game.Name)
|
||||
return
|
||||
}
|
||||
r := kafka.NewReader(kafka.ReaderConfig{
|
||||
Brokers: []string{"kafka-server:9092"},
|
||||
Topic: Game.Topic,
|
||||
Partition: Game.Partition,
|
||||
MinBytes: 10e3, // 10KB
|
||||
MaxBytes: 10e6, // 10MB
|
||||
})
|
||||
defer r.Close()
|
||||
// 设置读取超时时间
|
||||
offset := db.GetOffset(sqlDb)
|
||||
r.SetOffset(offset)
|
||||
ctx := context.Background()
|
||||
log.Println("comsumer start ", Game.Name)
|
||||
for {
|
||||
// 读取消息
|
||||
m, err := r.ReadMessage(ctx)
|
||||
if err != nil {
|
||||
log.Println("comsumer close ", Game.Name)
|
||||
return
|
||||
}
|
||||
Wait.Add(1)
|
||||
err = db.ProcessMsg(sqlDb, m)
|
||||
if err != nil {
|
||||
log.Printf("comsumer %s error :%v", Game.Name, err)
|
||||
}
|
||||
Wait.Done()
|
||||
}
|
||||
}
|
||||
14
kafka/release/conf/conf.yml
Normal file
14
kafka/release/conf/conf.yml
Normal file
@ -0,0 +1,14 @@
|
||||
db:
|
||||
host: "rm-f8zd2030feam53n43.mysql.rds.aliyuncs.com"
|
||||
user: root
|
||||
password: "V00jJQcC5GQOSEoEXmTfFmBCTk1-g2lBT2n-YA9UUg=="
|
||||
port: 3306
|
||||
games:
|
||||
- name: "Merge_Pet_Local"
|
||||
topic: "Merge_Pet_Local"
|
||||
partition: 0
|
||||
db_name: "Merge_Pet_Local"
|
||||
- name: "Merge_Pet_Test"
|
||||
topic: "Merge_Pet_Test"
|
||||
partition: 0
|
||||
db_name: "Merge_Pet_Test"
|
||||
BIN
kafka/release/kafka_comsumer
Normal file
BIN
kafka/release/kafka_comsumer
Normal file
Binary file not shown.
2
kafka/release/log/kafka-comsumer.log
Normal file
2
kafka/release/log/kafka-comsumer.log
Normal file
@ -0,0 +1,2 @@
|
||||
2024/12/18 07:00:46 main.go:48: comsumer db Merge_Pet_Online not exist
|
||||
2024/12/18 07:00:46 main.go:63: comsumer start Merge_Pet_Local
|
||||
2
kafka/release/logs
Normal file
2
kafka/release/logs
Normal file
@ -0,0 +1,2 @@
|
||||
/data/pet_home_devops/kafka/release/conf/conf.yml
|
||||
/data/pet_home_devops/kafka/release/conf/conf.yml
|
||||
51
kafka/release/start.sh
Normal file
51
kafka/release/start.sh
Normal file
@ -0,0 +1,51 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Restart the kafka comsumer service
|
||||
|
||||
# 获取命令行参数
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage: $0 [start|stop|status|restart]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $1 == "start" ]; then
|
||||
echo "Starting kafka comsumer..."
|
||||
> log/kafka-comsumer.log # 清空 logs 文件
|
||||
nohup ./kafka_comsumer >> logs 2>&1 &
|
||||
echo "kafka comsumer started."
|
||||
elif [ $1 == "stop" ]; then
|
||||
echo "Stopping kafka comsumer..."
|
||||
PID=$(ps -ef | grep kafka_comsumer | grep -v "grep" | awk '{print $2}')
|
||||
if [ -z $PID ]; then
|
||||
echo "kafka comsumer is not running."
|
||||
exit 1
|
||||
fi
|
||||
ps -ef | grep kafka_comsumer | grep -v grep | awk '{print $2}' | xargs kill
|
||||
echo "kafka comsumer stopped."
|
||||
elif [ $1 == "status" ]; then
|
||||
echo "kafka comsumer status:"
|
||||
PID=$(ps -ef | grep kafka_comsumer | grep -v "grep" | awk '{print $2}')
|
||||
if [ -z $PID ]; then
|
||||
echo "kafka comsumer is not running."
|
||||
else
|
||||
echo "kafka comsumer is running."
|
||||
fi
|
||||
elif [ $1 == "restart" ]; then
|
||||
echo "Restarting kafka comsumer..."
|
||||
PID=$(ps -ef | grep kafka_comsumer | grep -v "grep" | awk '{print $2}')
|
||||
if [ -n $PID ]; then
|
||||
echo "kafka comsumer stoping."
|
||||
kill $PID
|
||||
fi
|
||||
while [ -n "$PID" ]; do
|
||||
sleep 1
|
||||
PID=$(ps -ef | grep kafka_comsumer | grep -v "grep" | awk '{print $2}')
|
||||
done
|
||||
echo "kafka comsumer stoped."
|
||||
> log/kafka-comsumer.log # 清空 logs 文件
|
||||
nohup kafka_comsumer >> logs 2>&1 &
|
||||
echo "kafka comsumer restarted."
|
||||
else
|
||||
echo "Usage: $0 [start|stop|status|restart]"
|
||||
exit 1
|
||||
fi
|
||||
37
kafka/sql/create.sql
Normal file
37
kafka/sql/create.sql
Normal file
@ -0,0 +1,37 @@
|
||||
/*==============================================================*/
|
||||
/* Database name: sg_gamedb */
|
||||
/* DBMS name: MySQL 5.5.17 */
|
||||
/* Created on: 2014-10-16 10:00:00 */
|
||||
/*==============================================================*/
|
||||
|
||||
create database if not exists Merge_Pet_Local CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
use Merge_Pet_Local;
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `log_var` (
|
||||
`Key` varchar(128) DEFAULT '' COMMENT '键',
|
||||
`Value` varchar(128) DEFAULT '' COMMENT '值',
|
||||
`Timestamp` int DEFAULT 0 COMMENT '时间',
|
||||
PRIMARY KEY (`key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='登录日志';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `log_login` (
|
||||
`id` int unsigned AUTO_INCREMENT COMMENT '自增id',
|
||||
`Uid` int unsigned NOT NULL COMMENT '玩家id',
|
||||
`Event` varchar(128) DEFAULT '' COMMENT '事件',
|
||||
`Timestamp` int DEFAULT 0 COMMENT '时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `Event` (`Event`),
|
||||
KEY `Uid` (`Uid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='登录日志';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `log_event` (
|
||||
`id` int unsigned AUTO_INCREMENT COMMENT '自增id',
|
||||
`Uid` int unsigned NOT NULL COMMENT '玩家id',
|
||||
`Event` varchar(128) DEFAULT '' COMMENT '事件',
|
||||
`Param` text COMMENT '参数',
|
||||
`Timestamp` int DEFAULT 0 COMMENT '时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `Event` (`Event`),
|
||||
KEY `Uid` (`Uid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作事件';
|
||||
23
kafka/unit_test.go
Normal file
23
kafka/unit_test.go
Normal file
@ -0,0 +1,23 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"kafka-comsumer/util"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEncrypt(t *testing.T) {
|
||||
str, err := util.Encrypt("Z4rf7eZZe500dxa", util.SECRET_KEY)
|
||||
if err != nil {
|
||||
t.Errorf("Error: %v", err)
|
||||
}
|
||||
fmt.Print(str)
|
||||
}
|
||||
|
||||
func TestDecrypt(t *testing.T) {
|
||||
str, err := util.Decrypt("V00jJQcC5GQOSEoEXmTfFmBCTk1-g2lBT2n-YA9UUg==", util.SECRET_KEY)
|
||||
if err != nil {
|
||||
t.Errorf("Error: %v", err)
|
||||
}
|
||||
fmt.Print(str)
|
||||
}
|
||||
64
kafka/util/util.go
Normal file
64
kafka/util/util.go
Normal file
@ -0,0 +1,64 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
SECRET_KEY = ")VQbB(vpy=U(wcp)"
|
||||
)
|
||||
|
||||
// 加密字符串
|
||||
func Encrypt(plainText, key string) (string, error) {
|
||||
block, err := aes.NewCipher([]byte(key))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
cipherText := make([]byte, aes.BlockSize+len(plainText))
|
||||
iv := cipherText[:aes.BlockSize]
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
stream := cipher.NewCFBEncrypter(block, iv)
|
||||
stream.XORKeyStream(cipherText[aes.BlockSize:], []byte(plainText))
|
||||
|
||||
return base64.URLEncoding.EncodeToString(cipherText), nil
|
||||
}
|
||||
|
||||
// 解密字符串
|
||||
func Decrypt(cipherText, key string) (string, error) {
|
||||
cipherTextBytes, err := base64.URLEncoding.DecodeString(cipherText)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher([]byte(key))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if len(cipherTextBytes) < aes.BlockSize {
|
||||
return "", fmt.Errorf("cipherText too short")
|
||||
}
|
||||
|
||||
iv := cipherTextBytes[:aes.BlockSize]
|
||||
cipherTextBytes = cipherTextBytes[aes.BlockSize:]
|
||||
|
||||
stream := cipher.NewCFBDecrypter(block, iv)
|
||||
stream.XORKeyStream(cipherTextBytes, cipherTextBytes)
|
||||
|
||||
return string(cipherTextBytes), nil
|
||||
}
|
||||
|
||||
func GetNowTime() int64 {
|
||||
T := time.Now()
|
||||
return T.Unix()
|
||||
}
|
||||
40
nginx/gitea.conf
Normal file
40
nginx/gitea.conf
Normal file
@ -0,0 +1,40 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name gitea.bywaystudios.com;
|
||||
|
||||
# 将 HTTP 请求重定向到 HTTPS
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name gitea.bywaystudios.com;
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/gitea.bywaystudios.com.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/gitea.bywaystudios.com.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:8080;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /kafka {
|
||||
proxy_pass http://localhost:500/ui;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# 可选:配置日志文件
|
||||
access_log /var/log/nginx/gitea_access.log;
|
||||
error_log /var/log/nginx/gitea_error.log;
|
||||
}
|
||||
|
||||
31
nginx/tcp.conf
Normal file
31
nginx/tcp.conf
Normal file
@ -0,0 +1,31 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name pethome.bywaystudios.com;
|
||||
|
||||
# 将 HTTP 请求重定向到 HTTPS
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name pethome.bywaystudios.com;
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/pethome.bywaystudios.com.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/pethome.bywaystudios.com.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:8080;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# 可选:配置日志文件
|
||||
access_log /var/log/nginx/pethome_access.log;
|
||||
error_log /var/log/nginx/pethome_error.log;
|
||||
}
|
||||
4
pack.sh
4
pack.sh
@ -1,2 +1,2 @@
|
||||
cd /data/pet_home/src/server
|
||||
GOOS=linux GOARCH=amd64 go build -o /data/devops/source/main main.go
|
||||
cd /data/pet_home_server/src/server
|
||||
GOOS=linux GOARCH=amd64 go build -o /data/pet_home_devops/source/main main.go
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
- name: Deploy GoLeaf release
|
||||
hosts: compose
|
||||
hosts: zone1
|
||||
remote_user: root
|
||||
|
||||
tasks:
|
||||
@ -12,19 +12,19 @@
|
||||
# - name: tar
|
||||
# command: tar -xvf /usr/local/Goleaf.tar -C /usr/local/
|
||||
- name: sh pack.sh
|
||||
shell: sh /data/devops/pack.sh
|
||||
shell: sh /data/pet_home_devops/pack.sh
|
||||
delegate_to: localhost
|
||||
|
||||
- name: copy goleaf
|
||||
copy:
|
||||
src: /data/devops/source/main
|
||||
src: /data/pet_home_devops/source/main
|
||||
dest: /usr/local/Goleaf
|
||||
|
||||
- name: copy config
|
||||
copy:
|
||||
src: /data/docs/tool/out/
|
||||
dest: /usr/local/Goleaf/gamedata/config/
|
||||
mode: '0777'
|
||||
# - name: copy config
|
||||
# copy:
|
||||
# src: /data/pet_homedocs/tool/out/
|
||||
# dest: /usr/local/Goleaf/gamedata/config/
|
||||
# mode: '0777'
|
||||
|
||||
|
||||
# - name: restart goleaf
|
||||
|
||||
27
playbook/goleaf-conf.yml
Normal file
27
playbook/goleaf-conf.yml
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
- name: Deploy GoLeaf release
|
||||
hosts: test
|
||||
remote_user: root
|
||||
|
||||
tasks:
|
||||
|
||||
|
||||
- name: copy config
|
||||
copy:
|
||||
src: /data/pet_homedocs/tool/out/
|
||||
dest: /usr/local/Goleaf/gamedata/config/
|
||||
mode: '0777'
|
||||
- name: reload config
|
||||
command: echo "1" > /usr/local/Goleaf/gamedata/config/reload
|
||||
register: reload_result
|
||||
|
||||
- name: copy config2
|
||||
copy:
|
||||
src: /data/pet_homedocs/tool/out/
|
||||
dest: /usr/local/game/gamedata/config/
|
||||
mode: '0777'
|
||||
- name: reload config
|
||||
command: echo "1" > /usr/local/game/gamedata/config/reload
|
||||
register: reload_result
|
||||
|
||||
|
||||
53
playbook/goleaf-google.yml
Normal file
53
playbook/goleaf-google.yml
Normal file
@ -0,0 +1,53 @@
|
||||
---
|
||||
- name: Deploy GoLeaf release
|
||||
hosts: google
|
||||
remote_user: root
|
||||
vars:
|
||||
goleaf_src: /data/pet_home_devops/source/main
|
||||
goleaf_dest: /usr/local/game
|
||||
config_src: /data/pet_homedocs/tool/out/
|
||||
config_dest: /usr/local/game/gamedata/config/
|
||||
pack_script: /data/pet_home_devops/pack.sh
|
||||
tar_file: /usr/local/Goleaf.tar
|
||||
tar_dest: /usr/local/game
|
||||
|
||||
tasks:
|
||||
# - name: copy goleaf
|
||||
# command: tar -cvf /usr/local/Goleaf.tar -C /data/pet_home_devops/Goleaf .
|
||||
# delegate_to: localhost
|
||||
# - name: copy tar
|
||||
# copy:
|
||||
# src: /usr/local/Goleaf.tar
|
||||
# dest: /usr/local/game
|
||||
# - name : untar
|
||||
# command: tar -xvf /usr/local/game/Goleaf.tar -C /usr/local/game
|
||||
- name: sh pack.sh
|
||||
shell: sh /data/pet_home_devops/pack.sh
|
||||
delegate_to: localhost
|
||||
- name: stop goleaf
|
||||
command: sh "{{ goleaf_dest }}"/Restart.sh stop
|
||||
register: restart_result
|
||||
|
||||
- name: copy goleaf
|
||||
copy:
|
||||
src: "{{ goleaf_src }}"
|
||||
dest: "{{goleaf_dest}}"
|
||||
|
||||
- name: copy goleaf
|
||||
command: tar -cvf /usr/local/conf.tar -C /data/pet_homedocs/tool/out .
|
||||
delegate_to: localhost
|
||||
- name: copy tar
|
||||
copy:
|
||||
src: /usr/local/conf.tar
|
||||
dest: /usr/local/game
|
||||
- name : untar
|
||||
command: tar -xvf /usr/local/game/conf.tar -C /usr/local/game/gamedata/config/
|
||||
|
||||
|
||||
- name: restart goleaf
|
||||
command: sh "{{ goleaf_dest }}"/Restart.sh start
|
||||
register: restart_result
|
||||
|
||||
- name: show restart result
|
||||
debug:
|
||||
var: restart_result.stdout_lines
|
||||
53
playbook/goleaf-sdk.yml
Normal file
53
playbook/goleaf-sdk.yml
Normal file
@ -0,0 +1,53 @@
|
||||
---
|
||||
- name: Deploy GoLeaf release
|
||||
hosts: test
|
||||
remote_user: root
|
||||
vars:
|
||||
goleaf_src: /data/pet_home_devops/source/main
|
||||
goleaf_dest: /usr/local/game
|
||||
config_src: /data/pet_homedocs/tool/out/
|
||||
config_dest: /usr/local/game/gamedata/config/
|
||||
pack_script: /data/pet_home_devops/pack.sh
|
||||
tar_file: /usr/local/Goleaf.tar
|
||||
tar_dest: /usr/local/game
|
||||
|
||||
tasks:
|
||||
# - name: copy goleaf
|
||||
# command: tar -cvf /usr/local/Goleaf.tar -C /data/pet_home_devops/Goleaf .
|
||||
# delegate_to: localhost
|
||||
# - name: copy tar
|
||||
# copy:
|
||||
# src: /usr/local/Goleaf.tar
|
||||
# dest: /usr/local/game
|
||||
# - name : untar
|
||||
# command: tar -xvf /usr/local/game/Goleaf.tar -C /usr/local/game
|
||||
- name: sh pack.sh
|
||||
shell: sh /data/pet_home_devops/pack.sh
|
||||
delegate_to: localhost
|
||||
- name: restart goleaf
|
||||
command: sh "{{ goleaf_dest }}"/Restart.sh stop
|
||||
register: restart_result
|
||||
|
||||
- name: copy goleaf
|
||||
copy:
|
||||
src: "{{ goleaf_src }}"
|
||||
dest: "{{goleaf_dest}}"
|
||||
|
||||
- name: copy goleaf
|
||||
command: tar -cvf /usr/local/conf.tar -C /data/pet_homedocs/tool/out .
|
||||
delegate_to: localhost
|
||||
- name: copy tar
|
||||
copy:
|
||||
src: /usr/local/conf.tar
|
||||
dest: /usr/local/game
|
||||
- name : untar
|
||||
command: tar -xvf /usr/local/game/conf.tar -C /usr/local/game/gamedata/config/
|
||||
|
||||
|
||||
- name: restart goleaf
|
||||
command: sh "{{ goleaf_dest }}"/Restart.sh start
|
||||
register: restart_result
|
||||
|
||||
- name: show restart result
|
||||
debug:
|
||||
var: restart_result.stdout_lines
|
||||
@ -4,26 +4,38 @@
|
||||
remote_user: root
|
||||
|
||||
tasks:
|
||||
- name: sh pack.sh
|
||||
shell: sh /data/devops/pack.sh
|
||||
delegate_to: localhost
|
||||
# - name: restart goleaf
|
||||
# command: sh /usr/local/Goleaf/Restart.sh stop
|
||||
# register: restart_result
|
||||
|
||||
# - name: sh pack.sh
|
||||
# shell: sh /data/pet_home_devops/pack.sh
|
||||
# delegate_to: localhost
|
||||
|
||||
# - name: copy goleaf
|
||||
# copy:
|
||||
# src: /data/pet_home_devops/Goleaf/tool/tool
|
||||
# dest: /usr/local/Goleaf/tool
|
||||
# - name: copy goleaf
|
||||
# copy:
|
||||
# src: /data/pet_home_devops/source/main
|
||||
# dest: /usr/local/Goleaf
|
||||
|
||||
- name: copy goleaf
|
||||
command: tar -cvf /usr/local/conf.tar -C /data/pet_homedocs/tool/out .
|
||||
delegate_to: localhost
|
||||
- name: copy tar
|
||||
copy:
|
||||
src: /data/devops/source/main
|
||||
src: /usr/local/conf.tar
|
||||
dest: /usr/local/Goleaf
|
||||
|
||||
- name: copy config
|
||||
copy:
|
||||
src: /data/docs/tool/out/
|
||||
dest: /usr/local/Goleaf/gamedata/config/
|
||||
mode: '0777'
|
||||
- name : untar
|
||||
command: tar -xvf /usr/local/Goleaf/conf.tar -C /usr/local/Goleaf/gamedata/config/
|
||||
|
||||
|
||||
- name: restart goleaf
|
||||
command: sh /usr/local/Goleaf/Restart.sh restart
|
||||
register: restart_result
|
||||
# - name: restart goleaf
|
||||
# command: sh /usr/local/Goleaf/Restart.sh start
|
||||
# register: restart_result
|
||||
|
||||
- name: show restart result
|
||||
debug:
|
||||
var: restart_result.stdout_lines
|
||||
# - name: show restart result
|
||||
# debug:
|
||||
# var: restart_result.stdout_lines
|
||||
|
||||
@ -1,8 +1,17 @@
|
||||
[test]
|
||||
test ansible_ssh_host=1.15.182.107 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
a1 ansible_ssh_host=1.15.182.107 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
|
||||
[compose]
|
||||
center ansible_ssh_host=172.20.0.2 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
zone1 ansible_ssh_host=172.20.0.3 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
zone2 ansible_ssh_host=172.20.0.4 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
c1 ansible_ssh_host=172.20.0.2 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
z1 ansible_ssh_host=172.20.0.3 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
z2 ansible_ssh_host=172.20.0.4 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
|
||||
[zone1]
|
||||
a2 ansible_ssh_host=172.20.0.3 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
|
||||
[google]
|
||||
g1 ansible_ssh_host=47.254.83.25 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
|
||||
[release]
|
||||
a1 ansible_ssh_host=1.15.182.107 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
g1 ansible_ssh_host=47.254.83.25 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
|
||||
1344
playbook/package-lock.json
generated
Normal file
1344
playbook/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
5
playbook/package.json
Normal file
5
playbook/package.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"protobufjs-cli": "^1.1.3"
|
||||
}
|
||||
}
|
||||
BIN
script/20241216.xlsx
Normal file
BIN
script/20241216.xlsx
Normal file
Binary file not shown.
@ -22,15 +22,16 @@ server = SSHTunnelForwarder(
|
||||
server.start()
|
||||
db_host = server.local_bind_host
|
||||
db_port = server.local_bind_port
|
||||
RID = 100016
|
||||
MYRID = 100002
|
||||
print(db_host, db_port)
|
||||
RID = 200090
|
||||
MYRID = 100004
|
||||
|
||||
conn = pymysql.connect(
|
||||
host=db_host,
|
||||
port=db_port,
|
||||
user="root",
|
||||
password="Z4rf7eZZe500dxa",
|
||||
database="Merge_Pet"
|
||||
database="Merge_Pet_sdk"
|
||||
)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(("select * from t_player_mod where dwUin = {rid}").format(rid = RID))
|
||||
|
||||
2392
script/tools.ipynb
2392
script/tools.ipynb
File diff suppressed because it is too large
Load Diff
BIN
source/docker-ce-26.1.4-1.el7.x86_64.rpm
Normal file
BIN
source/docker-ce-26.1.4-1.el7.x86_64.rpm
Normal file
Binary file not shown.
BIN
source/mysql80-community-release-el7-11.noarch.rpm
Normal file
BIN
source/mysql80-community-release-el7-11.noarch.rpm
Normal file
Binary file not shown.
27
ssl/pethome.bywaystudios.com.key
Normal file
27
ssl/pethome.bywaystudios.com.key
Normal file
@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAo6z7cPVcCIu+rT6ywB5dhhpZfCiKQu155+XPR1kmMFwiFVQe
|
||||
XnzcT5kmdHLJVEZOgV+LM76SeiGi7haF3wH9N9uYUMmp91b4H2IAiybaKGl/Xc7M
|
||||
WWpn5YJcttCdd3ZfzYqRQoysucmi4qTzSwf3vJqijo+JFmDvolVWO0KtDsRmU6DL
|
||||
nocygaKROyyCh5HbWZnikb0bUTLYu58zhYvc1eFwrfwjRSPsGDcTbFHWCl1UNnfZ
|
||||
mWO0ydMnbfzUSQTGJmOVwqFkhMVRGFFjrTRUAeDNQpkr9YN8tGc+111Igq+uAfMc
|
||||
yrIIlfEy2ltSnu8hxjNb4sk5v9Fv7APkrjGVsQIDAQABAoIBAALK+8Fm/NDyg+iH
|
||||
fNv1YknDBYrhhpzZjSGtYYOWQr+pgTViKZOzYSKeLbKBl1J8uDzR6T/fsFBgMykJ
|
||||
flnnU6+Fa9k/dhe2RrNplzIvEaLsTFP79UjptwGK320ixl6yL04d337f6qSci07l
|
||||
wXcJMquBUf78j22WOt1gxAEGRFcccNj4yTxLOAFUqwegBy9MuH02VCW4z9QEwiWU
|
||||
MmQHbFIpHreJaIh+CaBWx9CUEzL4iCYqRnmSNgfw5AE0snvXid1tlQT4IBRvcPE4
|
||||
I2bRKUcxvckXHpVKbNPv2A43DoWjF+vlGjU6utMfZ5DRJWyn03s4HOAtrUGY48Sj
|
||||
0kNDbOECgYEAzSZYgqJuNXEzuZ9dYeXwvCdmU+krOUGaRu1gAymkRdSu+KFDxaTs
|
||||
xnbhbC0uUzSL0idqeUt3DpeV5rGJf8InbCVwTjmV8hKGS9zTMvBWAH4TavZswAJz
|
||||
/MNKXZ96UR9xRZFU4988pMF/yqliCLUgN8FI0KvAdIiMgJt4XWa0UUkCgYEAzD7s
|
||||
n9F7vo7ZHYt/L81lviw4+BBk1934LIvZsXadxmUE8S46ZgbqRZHbrErQ4GJGpCsc
|
||||
tGAsJpubDapGHv8iL5e6eUphHsM1wR18ciCSNjkxcvSiQJcCpzXLgDY8Tg7KxIOF
|
||||
c+HKH5O+awCIJcRBBZIXgTC6Gxy6IFee/GXNCSkCgYA0h4YQZSENJCBXflv97k/X
|
||||
Dcug3sqHjanAUZXNGYOLserflQNyf0l1hAkyltsOyRyoQhl8V3tzzBLBEGKhyQgp
|
||||
I+j+zrX7Vwz2LeQSXgHXfHDiaZjtDXO/nA3VrTk3vnJVmuH+uzGfCkD7lqWYjzBh
|
||||
tmc7r07HSBOZ9rU6TUsMqQKBgQCEoPPNEB4X7vDj85rCstE3vcW8qACkALrQSnwx
|
||||
dgIcO6sK5mb7q8/jH0UTy315x7dxkaFRLAZfh7oXFJP2Oty7JP7tFjSc4kx8u6X9
|
||||
AlOPrHIE4QCfirApXpBoEE/2rDpVg8ZcKqmy+aC0ISNHyvoiIOzscnTXeD8RE3Tl
|
||||
F0IeiQKBgAMSt0sbXy7jgBSUgK8GU5Ox2YcstNMJfeXu5F7WjbtuAlwMNJgBLVYd
|
||||
gM2lEE8xBUx/5wPkbvzJq4tRPzNO5T7AjOnYH1Ul2iz+kEDOZfPVL0OL/VUYFBYg
|
||||
4SZnnt1jC9aHLHVqVIIJK//9cEfOJZ6mz3DtyX2wDm/tdoFOr4cG
|
||||
-----END RSA PRIVATE KEY-----
|
||||
62
ssl/pethome.bywaystudios.com.pem
Normal file
62
ssl/pethome.bywaystudios.com.pem
Normal file
@ -0,0 +1,62 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIGCDCCBPCgAwIBAgIQA0IfJS+AMdxZgd8L1fUl/TANBgkqhkiG9w0BAQsFADBu
|
||||
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
||||
d3cuZGlnaWNlcnQuY29tMS0wKwYDVQQDEyRFbmNyeXB0aW9uIEV2ZXJ5d2hlcmUg
|
||||
RFYgVExTIENBIC0gRzIwHhcNMjQxMjA5MDAwMDAwWhcNMjUwMzA5MjM1OTU5WjAj
|
||||
MSEwHwYDVQQDExhwZXRob21lLmJ5d2F5c3R1ZGlvcy5jb20wggEiMA0GCSqGSIb3
|
||||
DQEBAQUAA4IBDwAwggEKAoIBAQCjrPtw9VwIi76tPrLAHl2GGll8KIpC7Xnn5c9H
|
||||
WSYwXCIVVB5efNxPmSZ0cslURk6BX4szvpJ6IaLuFoXfAf0325hQyan3VvgfYgCL
|
||||
JtooaX9dzsxZamflgly20J13dl/NipFCjKy5yaLipPNLB/e8mqKOj4kWYO+iVVY7
|
||||
Qq0OxGZToMuehzKBopE7LIKHkdtZmeKRvRtRMti7nzOFi9zV4XCt/CNFI+wYNxNs
|
||||
UdYKXVQ2d9mZY7TJ0ydt/NRJBMYmY5XCoWSExVEYUWOtNFQB4M1CmSv1g3y0Zz7X
|
||||
XUiCr64B8xzKsgiV8TLaW1Ke7yHGM1viyTm/0W/sA+SuMZWxAgMBAAGjggLrMIIC
|
||||
5zAfBgNVHSMEGDAWgBR435GQX+7erPbFdevVTFVT7yRKtjAdBgNVHQ4EFgQUKDRG
|
||||
tBU/MaYUiXNhjO+s2+fcgs0wIwYDVR0RBBwwGoIYcGV0aG9tZS5ieXdheXN0dWRp
|
||||
b3MuY29tMD4GA1UdIAQ3MDUwMwYGZ4EMAQIBMCkwJwYIKwYBBQUHAgEWG2h0dHA6
|
||||
Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYw
|
||||
FAYIKwYBBQUHAwEGCCsGAQUFBwMCMIGABggrBgEFBQcBAQR0MHIwJAYIKwYBBQUH
|
||||
MAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBKBggrBgEFBQcwAoY+aHR0cDov
|
||||
L2NhY2VydHMuZGlnaWNlcnQuY29tL0VuY3J5cHRpb25FdmVyeXdoZXJlRFZUTFND
|
||||
QS1HMi5jcnQwDAYDVR0TAQH/BAIwADCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFo
|
||||
AHYATnWjJ1yaEMM4W2zU3z9S6x3w4I4bjWnAsfpksWKaOd8AAAGTqSjTewAABAMA
|
||||
RzBFAiBZVs4LrOREOEnv8tQKb5UNFkPVfV2nNqCy24bKLAVr/gIhAMg2KsKQ9a6q
|
||||
8Wc64AKJx3DjFqLFpCytkTVKtrBp0tUzAHUAcyAiDwgWivnzxKaLCrJqmkoA7vV3
|
||||
hYoITQUA1KVCRFkAAAGTqSjTHwAABAMARjBEAiAiy4Xqcy0oqGMDDBRManyt6VmT
|
||||
jCZRVA+mHBzoQT0NAgIgOCW5513LuInmKGlKi5jxRkIM0xh6te0uIQvt4ze9EekA
|
||||
dwDm0jFjQHeMwRBBBtdxuc7B0kD2loSG+7qHMh39HjeOUAAAAZOpKNMvAAAEAwBI
|
||||
MEYCIQDFKi06ApokpmIizAxE+175uD3bIYO9P3+otQg1ZjSiUQIhAJ0SThOlYjU6
|
||||
1nvXCCVCrj96Jsb1KuKUdtPAelusunAHMA0GCSqGSIb3DQEBCwUAA4IBAQCoWphr
|
||||
4DagcE2yZJkgbhtJ05HLnFBqaQQ5+7X6SR/MRAPY65nCKzgntzXvBcpexiF04I2u
|
||||
ivtR0sH28Riuu+VDL4ltjZQsW20hd0QNeKia4caUaOaX0hEG1EO0sGLfHQI0G+oq
|
||||
jtEuSQnnzy2El3gs0kORAFqhGkL2q56rscPpandzdF1H5v2CeM54Q9EmCFzwGW7e
|
||||
NbLm7MSbn0enWs9q/Zjs6+t9n4VYFZw2c8BXDXtrim35ZcJpJZ7D91ve5SaMH5yg
|
||||
5at5un2nAdDe3D3V1aATz5ebq3M0JHoqkmPE1a3CkzMdfA8CQArmClBn8gquxm/+
|
||||
dq4rSsSh89wAz+lO
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEqjCCA5KgAwIBAgIQDeD/te5iy2EQn2CMnO1e0zANBgkqhkiG9w0BAQsFADBh
|
||||
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
||||
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
|
||||
MjAeFw0xNzExMjcxMjQ2NDBaFw0yNzExMjcxMjQ2NDBaMG4xCzAJBgNVBAYTAlVT
|
||||
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
|
||||
b20xLTArBgNVBAMTJEVuY3J5cHRpb24gRXZlcnl3aGVyZSBEViBUTFMgQ0EgLSBH
|
||||
MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO8Uf46i/nr7pkgTDqnE
|
||||
eSIfCFqvPnUq3aF1tMJ5hh9MnO6Lmt5UdHfBGwC9Si+XjK12cjZgxObsL6Rg1njv
|
||||
NhAMJ4JunN0JGGRJGSevbJsA3sc68nbPQzuKp5Jc8vpryp2mts38pSCXorPR+sch
|
||||
QisKA7OSQ1MjcFN0d7tbrceWFNbzgL2csJVQeogOBGSe/KZEIZw6gXLKeFe7mupn
|
||||
NYJROi2iC11+HuF79iAttMc32Cv6UOxixY/3ZV+LzpLnklFq98XORgwkIJL1HuvP
|
||||
ha8yvb+W6JislZJL+HLFtidoxmI7Qm3ZyIV66W533DsGFimFJkz3y0GeHWuSVMbI
|
||||
lfsCAwEAAaOCAU8wggFLMB0GA1UdDgQWBBR435GQX+7erPbFdevVTFVT7yRKtjAf
|
||||
BgNVHSMEGDAWgBROIlQgGJXm427mD/r6uRLtBhePOTAOBgNVHQ8BAf8EBAMCAYYw
|
||||
HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8C
|
||||
AQAwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp
|
||||
Y2VydC5jb20wQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQu
|
||||
Y29tL0RpZ2lDZXJ0R2xvYmFsUm9vdEcyLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG
|
||||
/WwBAjAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BT
|
||||
MAgGBmeBDAECATANBgkqhkiG9w0BAQsFAAOCAQEAoBs1eCLKakLtVRPFRjBIJ9LJ
|
||||
L0s8ZWum8U8/1TMVkQMBn+CPb5xnCD0GSA6L/V0ZFrMNqBirrr5B241OesECvxIi
|
||||
98bZ90h9+q/X5eMyOD35f8YTaEMpdnQCnawIwiHx06/0BfiTj+b/XQih+mqt3ZXe
|
||||
xNCJqKexdiB2IWGSKcgahPacWkk/BAQFisKIFYEqHzV974S3FAz/8LIfD58xnsEN
|
||||
GfzyIDkH3JrwYZ8caPTf6ZX9M1GrISN8HnWTtdNCH2xEajRa/h9ZBXjUyFKQrGk2
|
||||
n2hcLrfZSbynEC/pSw/ET7H5nWwckjmAJ1l9fcnbqkU/pf6uMQmnfl0JQjJNSg==
|
||||
-----END CERTIFICATE-----
|
||||
226
tool/Merge_Pet.sql
Normal file
226
tool/Merge_Pet.sql
Normal file
@ -0,0 +1,226 @@
|
||||
/*==============================================================*/
|
||||
/* Database name: sg_gamedb */
|
||||
/* DBMS name: MySQL 5.5.17 */
|
||||
/* Created on: 2014-10-16 10:00:00 */
|
||||
/*==============================================================*/
|
||||
|
||||
create database if not exists %database% CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
use %database%;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for db_version 版本号,每次更新数据库要改这个地方
|
||||
-- ----------------------------
|
||||
CREATE TABLE IF NOT EXISTS `db_version` (
|
||||
`version_2018_02_06_13` int unsigned NOT NULL COMMENT 'version'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据库版本号';
|
||||
|
||||
/*==============================================================*/
|
||||
/* Table: t_account 账号表 */
|
||||
/*==============================================================*/
|
||||
CREATE TABLE IF NOT EXISTS t_account
|
||||
(
|
||||
`user_name` varchar(50) NOT NULL,
|
||||
`user_password` varchar(128) NOT NULL,
|
||||
`login_time` int unsigned DEFAULT '0' COMMENT '上次登录时间',
|
||||
`logout_time` int unsigned DEFAULT '0' COMMENT '上次下线时间',
|
||||
`ip_address` char(24) DEFAULT '' COMMENT '上次登录的ip地址',
|
||||
`gm_level` int DEFAULT '0' COMMENT 'gm等级',
|
||||
`platform` varchar(50) DEFAULT '' COMMENT '平台',
|
||||
`is_online` int unsigned DEFAULT '0' COMMENT '角色是否在线',
|
||||
`channel` varchar(50) DEFAULT '' COMMENT '渠道号',
|
||||
`device_id` varchar(256) DEFAULT '' COMMENT '是否为刷榜账号',
|
||||
`auto_id` bigint NOT NULL auto_increment COMMENT '自增id',
|
||||
PRIMARY KEY (`auto_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='账号密码对照表';
|
||||
|
||||
/*==============================================================*/
|
||||
/* Table: t_gameserver GameServer表 */
|
||||
/*==============================================================*/
|
||||
CREATE TABLE IF NOT EXISTS t_gameserver
|
||||
(
|
||||
`id` int unsigned COMMENT '服务器id',
|
||||
`start_time` int unsigned COMMENT '开服时间',
|
||||
`close_time` int unsigned COMMENT '关服时间',
|
||||
`is_close` int unsigned COMMENT '是否关服',
|
||||
primary key(`id`)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='服务器设置';
|
||||
|
||||
|
||||
/*==============================================================*/
|
||||
/* Table: t_gameserver_info GameServer信息表 */
|
||||
/*==============================================================*/
|
||||
CREATE TABLE IF NOT EXISTS t_gameserver_info
|
||||
(
|
||||
`id` int unsigned COMMENT '服务器id',
|
||||
`growthfund_buynum` int unsigned NOT NULL DEFAULT '0' COMMENT '全服购买成长基金数量',
|
||||
`open_servertime` int unsigned NOT NULL DEFAULT '0' COMMENT '开服时间',
|
||||
`open_activeflag` int unsigned NOT NULL DEFAULT '0' COMMENT '开服活动完成发放奖励标示',
|
||||
`DailyRenewTime` int unsigned NOT NULL DEFAULT '0' COMMENT '日常刷新时间',
|
||||
primary key(`id`)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='全服全局数据';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_player_baseinfo
|
||||
-- ----------------------------
|
||||
CREATE TABLE IF NOT EXISTS `t_player_baseinfo` (
|
||||
`dwUin` int unsigned NOT NULL COMMENT '对应玩家account表中的dwUin',
|
||||
`energy` int unsigned NOT NULL DEFAULT '0' COMMENT '能量',
|
||||
`star` int unsigned NOT NULL DEFAULT '0' COMMENT '星星',
|
||||
`recover_time` int unsigned NOT NULL DEFAULT '0' COMMENT '能量开始恢复时间',
|
||||
`diamond` int unsigned NOT NULL DEFAULT '1' COMMENT '钻石',
|
||||
`level` int unsigned NOT NULL DEFAULT '0' COMMENT '玩家等级',
|
||||
`exp` int unsigned zerofill NOT NULL DEFAULT '0' COMMENT '玩家经验',
|
||||
`start_order_id` varchar(50) DEFAULT NULL COMMENT '配置订单进度',
|
||||
`music_code` int unsigned NOT NULL DEFAULT '0' COMMENT '音效状态码改为GUID免费改名状态',
|
||||
`guild` int unsigned NOT NULL DEFAULT '0' COMMENT '引导进度 ',
|
||||
`pack_unlock_count` int unsigned NOT NULL DEFAULT '0' COMMENT '背包解锁数量',
|
||||
`last_play_time` int NOT NULL DEFAULT '0' COMMENT '广告能量购买时间',
|
||||
`EnergyBuyCount` int NOT NULL DEFAULT '0' COMMENT '能量购买次数',
|
||||
`user_name` varchar(50) NOT NULL COMMENT '玩家账号',
|
||||
`login_time` int unsigned NOT NULL DEFAULT '0' COMMENT '上次登录时间',
|
||||
`logout_time` int unsigned NOT NULL DEFAULT '0' COMMENT '上次下线时间',
|
||||
`todayolinetime` int unsigned NOT NULL DEFAULT '0' COMMENT '当天的累计在线时间',
|
||||
`rolecreatetime` int unsigned NOT NULL DEFAULT '0' COMMENT '注册帐号时间',
|
||||
`EmitOrderCnt` int unsigned NOT NULL DEFAULT '0' COMMENT '注册帐号时间',
|
||||
`DailyRenewTime` int unsigned NOT NULL DEFAULT '0' COMMENT '注册帐号时间',
|
||||
`NoAd` int unsigned NOT NULL DEFAULT '0' COMMENT '注册帐号时间',
|
||||
`ChampshipsGroupID` int unsigned NOT NULL DEFAULT '0' COMMENT '注册帐号时间',
|
||||
`LastChampGroupID` int unsigned NOT NULL DEFAULT '0' COMMENT '注册帐号时间',
|
||||
`FaceBookId` varchar(128) DEFAULT '' COMMENT '玩家账号',
|
||||
PRIMARY KEY (`dwUin`),
|
||||
KEY `user_name` (`user_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='存储玩家基本信息';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table: t_player_auto_pup 客户端数据持久化表
|
||||
-- ----------------------------
|
||||
CREATE TABLE IF NOT EXISTS `t_player_auto_pup` (
|
||||
`dwUin` int unsigned NOT NULL COMMENT 'uid',
|
||||
`ReqKeys` varchar(2048) DEFAULT '' COMMENT 'key',
|
||||
`ReqVals` varchar(2048) DEFAULT '' COMMENT 'value',
|
||||
PRIMARY KEY (`dwUin`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='存储玩家基本信息';
|
||||
|
||||
|
||||
|
||||
/*==============================================================*/
|
||||
/* Table: t_player_data 玩家模块表 */
|
||||
/*==============================================================*/
|
||||
CREATE TABLE IF NOT EXISTS t_player_mod
|
||||
(
|
||||
`dwUin` int unsigned COMMENT '玩家uid',
|
||||
`mData` blob DEFAULT NULL COMMENT '数据',
|
||||
`updateTime` int unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
|
||||
primary key(`dwUin`)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='玩家模块表';
|
||||
|
||||
|
||||
|
||||
|
||||
/*==============================================================*/
|
||||
/* Table: t_player_data 玩家订单表 */
|
||||
/*==============================================================*/
|
||||
CREATE TABLE IF NOT EXISTS t_player_charge
|
||||
(
|
||||
`id`int unsigned AUTO_INCREMENT COMMENT '订单id',
|
||||
`Uid` int unsigned NOT NULL COMMENT '玩家id',
|
||||
`OrderId` varchar(128) DEFAULT '' COMMENT '订单号',
|
||||
`ProductId` int unsigned NOT NULL DEFAULT '0' COMMENT '商品id',
|
||||
`ProductName` varchar(128) DEFAULT '' COMMENT '商品名称',
|
||||
`ProductDesc` varchar(128) DEFAULT '' COMMENT '商品描述',
|
||||
`Price` float NOT NULL DEFAULT '0' COMMENT '价格',
|
||||
`Currency` varchar(128) DEFAULT '' COMMENT '货币',
|
||||
`CreateTime` int unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
|
||||
`PayTime` int unsigned NOT NULL DEFAULT '0' COMMENT '支付时间',
|
||||
`PayStatus` int unsigned NOT NULL DEFAULT '0' COMMENT '支付状态 0 未支付 1 已支付 2 支付失败 3 已发货',
|
||||
`PayType` int unsigned NOT NULL DEFAULT '0' COMMENT '支付类型',
|
||||
`PayPlatform` varchar(128) DEFAULT '' COMMENT '支付平台',
|
||||
`PayChannel` varchar(128) DEFAULT '' COMMENT '支付渠道',
|
||||
`PayChannelOrderId` varchar(128) DEFAULT '' COMMENT '支付渠道订单号',
|
||||
`PayChannelUserId` varchar(128) DEFAULT '' COMMENT '支付渠道用户id',
|
||||
`PayChannelExtra` varchar(128) DEFAULT '' COMMENT '支付渠道额外信息',
|
||||
primary key(`id`)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='玩家订单表';
|
||||
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for system_mail_info
|
||||
-- ----------------------------
|
||||
CREATE TABLE IF NOT EXISTS `system_mail_info` (
|
||||
`mail_id` bigint NOT NULL AUTO_INCREMENT COMMENT '邮件ID',
|
||||
`title` varchar(128) DEFAULT "" COMMENT '邮件标题',
|
||||
`content` varchar(2048) DEFAULT "" COMMENT '邮件内容',
|
||||
`items` varchar(2048) DEFAULT "{}" COMMENT '邮件附件',
|
||||
`start_time` int unsigned NOT NULL DEFAULT '0' COMMENT '开始时间',
|
||||
`register_time` int unsigned NOT NULL DEFAULT '0' COMMENT '注册时间',
|
||||
`end_time` int unsigned NOT NULL DEFAULT '0' COMMENT '结束时间',
|
||||
`mail_type` int unsigned NOT NULL DEFAULT '0' COMMENT '邮件类型',
|
||||
`to_uids` varchar(2048) DEFAULT "" COMMENT '发送者ID',
|
||||
PRIMARY KEY (`mail_id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='系统邮件';
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_player_daily_task_data
|
||||
-- ----------------------------
|
||||
CREATE TABLE IF NOT EXISTS `t_server_global_data` (
|
||||
`Id` int unsigned NOT NULL COMMENT '对应玩家account表中的dwUin',
|
||||
`StartMileStoneSvrTime` int unsigned NOT NULL DEFAULT '0' COMMENT '里程碑时间',
|
||||
`StartChampshipsSvrTime` int unsigned NOT NULL DEFAULT '0' COMMENT '锦标赛时间',
|
||||
`InsertChampshipsSvrTime` int unsigned NOT NULL DEFAULT '0' COMMENT '每半小时插入玩家排行锦标赛时间',
|
||||
`WaitToRank` text COMMENT '排名数据',
|
||||
`Limit4CardExclude` text COMMENT '排名数据',
|
||||
`Limit5CardExclude` text COMMENT '排名数据',
|
||||
`CurChampshipsId` int unsigned NOT NULL DEFAULT '0' COMMENT '锦标赛全局Id',
|
||||
`LastChampshipsId` int unsigned NOT NULL DEFAULT '0' COMMENT '锦标赛全局Id',
|
||||
`Limit4Card` int unsigned NOT NULL DEFAULT '0' COMMENT '限时4星金卡ID',
|
||||
`Limit5Card` int unsigned NOT NULL DEFAULT '0' COMMENT '限时5星金卡ID',
|
||||
`LimitCardSwapTime` int unsigned NOT NULL DEFAULT '0' COMMENT '限时5星金卡ID',
|
||||
`OpenSvrTime` int unsigned NOT NULL DEFAULT '0' COMMENT '锦标赛全局Id',
|
||||
PRIMARY KEY (`Id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='存储玩家基本信息';
|
||||
|
||||
|
||||
/*==============================================================*/
|
||||
/* Table: t_player_data 系统模块表 */
|
||||
/*==============================================================*/
|
||||
CREATE TABLE IF NOT EXISTS t_server_mod
|
||||
(
|
||||
`id` int NOT NULL AUTO_INCREMENT primary key,
|
||||
`key` varchar(128) DEFAULT '' COMMENT '模块key',
|
||||
`mData` mediumblob DEFAULT NULL COMMENT '数据',
|
||||
`updateTime` int unsigned NOT NULL DEFAULT '0' COMMENT '更新时间'
|
||||
) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='系统模块表';
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `t_log_login` (
|
||||
`id` int NOT NULL AUTO_INCREMENT primary key,
|
||||
`dwUin` int unsigned NOT NULL COMMENT '对应玩家account表中的dwUin',
|
||||
`type` int unsigned NOT NULL DEFAULT '0' COMMENT '日志类型',
|
||||
`event` varchar(512) DEFAULT '' COMMENT '事件名',
|
||||
`timestamp` int DEFAULT 0 COMMENT '时间错',
|
||||
KEY (`dwUin`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='玩家日志';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `t_log_evnet` (
|
||||
`id` int NOT NULL AUTO_INCREMENT primary key,
|
||||
`dwUin` int unsigned NOT NULL COMMENT '对应玩家account表中的dwUin',
|
||||
`type` int unsigned NOT NULL DEFAULT '0' COMMENT '日志类型',
|
||||
`event` varchar(512) DEFAULT '' COMMENT '事件名',
|
||||
`param` varchar(512) DEFAULT '' COMMENT '参数',
|
||||
`timestamp` int DEFAULT 0 COMMENT '时间错',
|
||||
KEY (`dwUin`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='玩家日志';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `t_log_item` (
|
||||
`dwUin` int unsigned NOT NULL COMMENT '对应玩家account表中的dwUin',
|
||||
`type` int unsigned NOT NULL DEFAULT '0' COMMENT '日志类型',
|
||||
`event` varchar(512) DEFAULT '' COMMENT '事件名',
|
||||
`timestamp` int DEFAULT 0 COMMENT '时间错',
|
||||
KEY (`dwUin`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='玩家日志';
|
||||
31
tool/app.ini
Normal file
31
tool/app.ini
Normal file
@ -0,0 +1,31 @@
|
||||
[app]
|
||||
app_name = pet_home
|
||||
app_id = 1001
|
||||
app_path = /data/pet_home_devops/Goleaf
|
||||
conf_path = /etc/pet_home
|
||||
[server]
|
||||
tcp_addr = 3600
|
||||
ws_addr = 3700
|
||||
listen_addr = 3800
|
||||
max_conn = 1000
|
||||
remote = pethome.bywaystudios.com
|
||||
|
||||
[mysql]
|
||||
mysql_user = root
|
||||
mysql_password = root
|
||||
mysql_host = 172.20.0.5
|
||||
mysql_port = 3306
|
||||
|
||||
[redis]
|
||||
redis_host = 172.20.0.6
|
||||
redis_port = 6379
|
||||
|
||||
[cluster]
|
||||
center_id = 0
|
||||
center_host = pethome.bywaystudios.com
|
||||
center_port = 3800
|
||||
|
||||
[log]
|
||||
log_level = debug
|
||||
te_log_path = /var/log/pet_home/te
|
||||
|
||||
7
tool/go.mod
Normal file
7
tool/go.mod
Normal file
@ -0,0 +1,7 @@
|
||||
module tool
|
||||
|
||||
go 1.23.1
|
||||
|
||||
require gopkg.in/ini.v1 v1.67.0
|
||||
|
||||
require github.com/stretchr/testify v1.10.0 // indirect
|
||||
10
tool/go.sum
Normal file
10
tool/go.sum
Normal file
@ -0,0 +1,10 @@
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
393
tool/main.go
Normal file
393
tool/main.go
Normal file
@ -0,0 +1,393 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
||||
// GOOS=linux GOARCH=amd64 go build -o /data/pet_home_devops/Goleaf/tool/tool main.go
|
||||
var help = `
|
||||
Usage: app.ini [options]
|
||||
|
||||
start start the server
|
||||
stop stop the server
|
||||
restart restart the server
|
||||
status get the server status
|
||||
|
||||
`
|
||||
var cfg *ini.File
|
||||
var FuncMap map[string]func() error
|
||||
var dirPath string
|
||||
var app_path string
|
||||
|
||||
func main() {
|
||||
FuncMap = make(map[string]func() error)
|
||||
// 检查是否提供了命令行参数
|
||||
if len(os.Args) < 2 {
|
||||
log.Fatal(help)
|
||||
}
|
||||
var err error
|
||||
|
||||
// 获取当前文件的绝对路径
|
||||
execPath, err := os.Executable()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
absPath, err := filepath.Abs(execPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// 获取当前文件的绝对路径的文件夹路径
|
||||
dirPath = filepath.Dir(absPath)
|
||||
|
||||
// 加载 app.ini 文件
|
||||
cfg, err = ini.Load(dirPath + "/app.ini")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
app_path = cfg.Section("app").Key("app_path").String()
|
||||
register("start", start)
|
||||
register("stop", stop)
|
||||
register("install", install)
|
||||
register("status", status)
|
||||
register("restart", restart)
|
||||
funcName := os.Args[1]
|
||||
if f, ok := FuncMap[funcName]; ok {
|
||||
e := f()
|
||||
if e != nil {
|
||||
log.Fatal(e)
|
||||
}
|
||||
} else {
|
||||
log.Fatal(help)
|
||||
}
|
||||
}
|
||||
|
||||
func register(name string, f func() error) {
|
||||
FuncMap[name] = f
|
||||
}
|
||||
|
||||
func install() error {
|
||||
fmt.Println("install")
|
||||
if len(os.Args) < 4 {
|
||||
log.Fatal("请输入要安装的服务类型和区号 install [center|node] 区号")
|
||||
}
|
||||
serverType := os.Args[2]
|
||||
zone := os.Args[3]
|
||||
if serverType != "center" && serverType != "node" {
|
||||
log.Fatal("请输入正确的服务类型 center|node")
|
||||
}
|
||||
AppName := cfg.Section("app").Key("app_name").String()
|
||||
// 生成服务名
|
||||
serviceName := fmt.Sprintf("%s_%s_%s", AppName, serverType, zone)
|
||||
// 判断文件夹是否存在
|
||||
folderPath := fmt.Sprintf("%s/zone/%s", app_path, serviceName)
|
||||
if _, err := os.Stat(folderPath); os.IsNotExist(err) {
|
||||
err := os.MkdirAll(folderPath, os.ModePerm)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("文件夹 %s 创建成功\n", folderPath)
|
||||
} else {
|
||||
fmt.Printf("文件夹 %s 已存在\n", folderPath)
|
||||
}
|
||||
|
||||
// 生成配置文件
|
||||
configPath := fmt.Sprintf("%s/server.json", folderPath)
|
||||
file, err := os.Create(configPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
zoneId, _ := strconv.Atoi(zone)
|
||||
cf, confs := createConfigFile(zoneId, serverType)
|
||||
file.WriteString(confs)
|
||||
|
||||
// 读取 SQL 文件内容并替换 %database% 字符串
|
||||
sqlFilePath := fmt.Sprintf("%s/tool/Merge_Pet.sql", app_path)
|
||||
sqlContent, err := os.ReadFile(sqlFilePath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
dbName := cf["DbName"].(string)
|
||||
modifiedSQL := strings.ReplaceAll(string(sqlContent), "%database%", dbName)
|
||||
|
||||
// 将修改后的内容写入临时文件
|
||||
tempSQLFile, err := os.CreateTemp("", "modified_*.sql")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// defer os.Remove(tempSQLFile.Name())
|
||||
_, err = tempSQLFile.WriteString(modifiedSQL)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
tempSQLFile.Close()
|
||||
|
||||
// 创建数据库
|
||||
dbUser := cfg.Section("mysql").Key("mysql_user").String()
|
||||
dbPassword := cfg.Section("mysql").Key("mysql_password").String()
|
||||
dbHost := cfg.Section("mysql").Key("mysql_host").String()
|
||||
dbPort := cfg.Section("mysql").Key("mysql_port").String()
|
||||
fmt.Println("mysql", "-u"+dbUser, "-p"+dbPassword, "-h"+dbHost, "-P"+dbPort, "-e", fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", dbName))
|
||||
createDBCmd := exec.Command("mysql", "-u"+dbUser, "-p"+dbPassword, "-h"+dbHost, "-P"+dbPort, "-e", fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", dbName))
|
||||
createDBCmd.Stdout = os.Stdout
|
||||
createDBCmd.Stderr = os.Stderr
|
||||
|
||||
err = createDBCmd.Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println("mysql", "-u"+dbUser, "-p"+dbPassword, "-h"+dbHost, "-P"+dbPort, dbName, "-e", fmt.Sprintf("source %s", tempSQLFile.Name()))
|
||||
// 执行修改后的 SQL 文件
|
||||
cmd := exec.Command("mysql", "-u"+dbUser, "-p"+dbPassword, "-h"+dbHost, "-P"+dbPort, dbName, "-e", fmt.Sprintf("source %s", tempSQLFile.Name()))
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
cmd = exec.Command("mkdir", cf["LogPath"].(string))
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("SQL 文件 %s 执行成功\n", sqlFilePath)
|
||||
fmt.Printf("配置文件 %s 创建成功\n", configPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
func createConfigFile(Id int, Type string) (map[string]interface{}, string) {
|
||||
conf := make(map[string]interface{})
|
||||
conf["LogLevel"] = cfg.Section("log").Key("log_level").String()
|
||||
|
||||
TcpStartAddr, _ := cfg.Section("server").Key("tcp_addr").Int()
|
||||
conf["TcpAddr"] = fmt.Sprintf(":%d", TcpStartAddr+Id)
|
||||
|
||||
WsStartAddr, _ := cfg.Section("server").Key("ws_addr").Int()
|
||||
conf["WsAddr"] = fmt.Sprintf(":%d", WsStartAddr+Id)
|
||||
|
||||
ListenAddr, _ := cfg.Section("server").Key("listen_addr").Int()
|
||||
|
||||
conf["MySqlAddr"] = cfg.Section("mysql").Key("mysql_host").String()
|
||||
conf["MySqlUsr"] = cfg.Section("mysql").Key("mysql_user").String()
|
||||
conf["MySqlPwd"] = cfg.Section("mysql").Key("mysql_password").String()
|
||||
conf["MySqlPort"] = cfg.Section("mysql").Key("mysql_port").String()
|
||||
MaxConnNum, _ := cfg.Section("server").Key("max_conn").Int()
|
||||
conf["MaxConnNum"] = MaxConnNum
|
||||
app_name := cfg.Section("app").Key("app_name").String()
|
||||
conf["LogPath"] = fmt.Sprintf("%s/zone/%s_%s_%d/log/", app_path, app_name, Type, Id)
|
||||
conf["DbName"] = fmt.Sprintf("%s_%d", app_name, Id)
|
||||
|
||||
conf["TELOGDIR"] = cfg.Section("log").Key("te_log_path").String()
|
||||
|
||||
conf["GameName"] = app_name
|
||||
AppId, _ := cfg.Section("app").Key("app_id").Int()
|
||||
conf["GameId"] = AppId
|
||||
|
||||
conf["ServerType"] = Type
|
||||
conf["ServerID"] = Id
|
||||
|
||||
conf["ServerOpenTime"] = "2028-01-01 00:00:00"
|
||||
conf["ServerName"] = fmt.Sprintf("%s_%d", app_name, Id)
|
||||
conf["ServerStatus"] = 1
|
||||
CenterId, _ := cfg.Section("app").Key("center_id").Int()
|
||||
conf["ServerCenter"] = CenterId
|
||||
|
||||
conf["RedisAddr"] = cfg.Section("redis").Key("redis_host").String()
|
||||
conf["RedisPort"] = cfg.Section("redis").Key("redis_port").String()
|
||||
conf["GameConfPath"] = app_path + "/config/"
|
||||
conf["RemoteAddr"] = fmt.Sprintf("%s:%d", cfg.Section("server").Key("remote").String(), ListenAddr+Id) // 服务器地址
|
||||
conf["ListenAddr"] = fmt.Sprintf(":%d", ListenAddr+Id)
|
||||
conf["CenterAddr"] = fmt.Sprintf("%s:%s", cfg.Section("cluster").Key("center_host").String(), cfg.Section("cluster").Key("center_port").String()) // 服务器地址
|
||||
b, _ := json.MarshalIndent(conf, "", " ")
|
||||
return conf, string(b)
|
||||
}
|
||||
|
||||
func start() error {
|
||||
fmt.Println("start")
|
||||
err := status()
|
||||
if err == nil {
|
||||
return err
|
||||
}
|
||||
NodeType := os.Args[2]
|
||||
Zone := os.Args[3]
|
||||
// 示例命令
|
||||
app_name := cfg.Section("app").Key("app_name").String()
|
||||
|
||||
cmdName := app_path + "/main"
|
||||
cmdArgs := []string{fmt.Sprintf("%s/zone/%s_%s_%s/server.json", app_path, app_name, NodeType, Zone)}
|
||||
|
||||
// 创建命令
|
||||
cmd := exec.Command(cmdName, cmdArgs...)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
||||
// 创建管道
|
||||
stdin, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
cmd.Env = os.Environ()
|
||||
// 打开输出文件
|
||||
outfile, err := os.OpenFile(fmt.Sprintf("%s/zone/%s_%s_%s/output.log", app_path, app_name, NodeType, Zone), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer outfile.Close()
|
||||
|
||||
// 重定向标准输出和标准错误到文件
|
||||
cmd.Stdout = outfile
|
||||
cmd.Stderr = outfile
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 打印进程号
|
||||
fmt.Printf("进程 %d 已启动\n", cmd.Process.Pid)
|
||||
|
||||
// 发送命令到子进程
|
||||
go func() {
|
||||
time.Sleep(2 * time.Second) // 等待子进程启动
|
||||
_, err := stdin.Write([]byte("your_command\n"))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
stdin.Close()
|
||||
}()
|
||||
|
||||
// 释放与子进程相关的资源
|
||||
err = cmd.Process.Release()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func stop() error {
|
||||
fmt.Println("stop")
|
||||
err := status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
NodeType := os.Args[2]
|
||||
Zone := os.Args[3]
|
||||
// 示例命令
|
||||
app_name := cfg.Section("app").Key("app_name").String()
|
||||
processName := fmt.Sprintf("%s/zone/%s_%s_%s/server.json", app_path, app_name, NodeType, Zone)
|
||||
// 示例进程名称
|
||||
|
||||
// 获取进程号
|
||||
pid, err := getPidByArgs(processName)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 查找进程
|
||||
process, err := os.FindProcess(pid)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 关闭进程
|
||||
err = process.Kill()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// // 等待子进程退出
|
||||
// _, err = process.Wait()
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
|
||||
fmt.Printf("进程 %d 已关闭\n", pid)
|
||||
return nil
|
||||
}
|
||||
|
||||
// func getPidByName(name string) (int, error) {
|
||||
// cmd := exec.Command("pgrep", name)
|
||||
// output, err := cmd.Output()
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
|
||||
// // 解析输出,获取第一个匹配的进程号
|
||||
// outputStr := strings.TrimSpace(string(output))
|
||||
// pidStr := strings.Split(outputStr, "\n")[0]
|
||||
// pid, err := strconv.Atoi(pidStr)
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
|
||||
// return pid, nil
|
||||
// }
|
||||
|
||||
func getPidByArgs(args string) (int, error) {
|
||||
cmd := exec.Command("pgrep", "-f", args)
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 解析输出,获取第一个匹配的进程号
|
||||
outputStr := strings.TrimSpace(string(output))
|
||||
pidStr := strings.Split(outputStr, "\n")[0]
|
||||
pid, err := strconv.Atoi(pidStr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return pid, nil
|
||||
}
|
||||
|
||||
func status() error {
|
||||
NodeType := os.Args[2]
|
||||
Zone := os.Args[3]
|
||||
// 示例命令
|
||||
app_name := cfg.Section("app").Key("app_name").String()
|
||||
processName := fmt.Sprintf("%s/zone/%s_%s_%s/server.json", app_path, app_name, NodeType, Zone)
|
||||
// 示例进程名称
|
||||
|
||||
// 获取进程号
|
||||
pid, err := getPidByArgs(processName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("进程 %s_%s 未启动", NodeType, Zone)
|
||||
}
|
||||
|
||||
// 查找进程
|
||||
_, err = os.FindProcess(pid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("进程 %s_%s 未启动", NodeType, Zone)
|
||||
}
|
||||
|
||||
fmt.Printf("节点 %s_%s 启动中, 进程号 %d\n", NodeType, Zone, pid)
|
||||
return nil
|
||||
}
|
||||
|
||||
func restart() error {
|
||||
fmt.Println("restart")
|
||||
err := stop()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for status() == nil {
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
err = start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
102
tool/tool.py
Normal file
102
tool/tool.py
Normal file
@ -0,0 +1,102 @@
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import configparser
|
||||
|
||||
help_message = """
|
||||
Usage: app.ini [options]
|
||||
|
||||
start start the server
|
||||
stop stop the server
|
||||
restart restart the server
|
||||
status get the server status
|
||||
"""
|
||||
|
||||
cfg = None
|
||||
FuncMap = {}
|
||||
dir_path = ""
|
||||
app_path = ""
|
||||
|
||||
def main():
|
||||
global cfg, dir_path, app_path
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print(help_message)
|
||||
sys.exit(1)
|
||||
|
||||
# 获取当前文件的绝对路径
|
||||
exec_path = os.path.abspath(sys.argv[0])
|
||||
dir_path = os.path.dirname(exec_path)
|
||||
# print(f"当前文件的绝对路径的文件夹路径: {dir_path}")
|
||||
|
||||
# 加载 app.ini 文件
|
||||
cfg = configparser.ConfigParser()
|
||||
cfg.read(os.path.join(dir_path, "app.ini"))
|
||||
app_path = cfg.get("app", "app_path")
|
||||
|
||||
register("start", start)
|
||||
register("stop", stop)
|
||||
|
||||
func_name = sys.argv[1]
|
||||
if func_name in FuncMap:
|
||||
FuncMap[func_name]()
|
||||
else:
|
||||
print(help_message)
|
||||
sys.exit(1)
|
||||
|
||||
def register(name, func):
|
||||
FuncMap[name] = func
|
||||
|
||||
def start():
|
||||
print("start")
|
||||
NodeType = sys.argv[2]
|
||||
Zone = sys.argv[3]
|
||||
app_name = cfg.get("app", "app_name")
|
||||
|
||||
cmd_name = app_path + "/main"
|
||||
cmd_args = [f"{app_path}/zone/{app_name}_{NodeType}_{Zone}/server.json"]
|
||||
|
||||
# 创建命令
|
||||
cmd = [cmd_name] + cmd_args
|
||||
print(cmd)
|
||||
|
||||
# 启动命令
|
||||
process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, start_new_session=True)
|
||||
print(f"p {process.pid} s")
|
||||
|
||||
# 获取命令输出
|
||||
stdout, stderr = process.communicate()
|
||||
print("e:", stdout.decode('utf-8', errors='ignore'))
|
||||
print("e2:", stderr.decode('utf-8', errors='ignore'))
|
||||
|
||||
def stop():
|
||||
print("stop")
|
||||
NodeType = sys.argv[2]
|
||||
Zone = sys.argv[3]
|
||||
app_name = cfg.get("app", "app_name")
|
||||
process_args = f"{app_path}/zone/{app_name}_{NodeType}_{Zone}/server.json"
|
||||
|
||||
# 获取进程号
|
||||
pid = get_pid_by_args(process_args)
|
||||
if pid is None:
|
||||
print("未找到进程")
|
||||
sys.exit(1)
|
||||
|
||||
# 关闭进程
|
||||
try:
|
||||
os.kill(pid, 9)
|
||||
print(f"进程 {pid} 已关闭")
|
||||
except OSError as e:
|
||||
print(f"关闭进程失败: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
def get_pid_by_args(args):
|
||||
try:
|
||||
output = subprocess.check_output(["pgrep", "-f", args])
|
||||
pid_str = output.decode().strip().split("\n")[0]
|
||||
return int(pid_str)
|
||||
except subprocess.CalledProcessError:
|
||||
return None
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Reference in New Issue
Block a user