diff --git a/bin/gm.json b/bin/gm.json new file mode 100644 index 000000000..008a32e04 --- /dev/null +++ b/bin/gm.json @@ -0,0 +1,47 @@ +{ + "AreaId": "dfli01", + "ConsulAddr": "10.0.0.9:10012", + "IsCross": false, + "BelongCrossServerId": "dflicross01", + "LoaclDB": { + "RedisIsCluster": false, + "RedisAddr": "10.0.0.9:10011", + "RedisPassword": "li13451234", + "RedisDB": 5, + "MongodbUrl": "mongodb://10.0.0.9:10013", + "MongodbDatabase": "dreamfactory5" + }, + "CrossDB": { + "RedisIsCluster": false, + "RedisAddr": "10.0.0.9:10011", + "RedisPassword": "li13451234", + "RedisDB": 6, + "MongodbUrl": "mongodb://10.0.0.9:10013", + "MongodbDatabase": "dreamfactory6" + }, + "Services": [ + { + "ServiceType": "gateway", + "Host": "127.0.0.1", + "Port": 9567, + "Loglevel": 5, + "MaxAgeTime": 7, + "ListenPort": 7891 + }, + { + "ServiceType": "mainte", + "Host": "127.0.0.1", + "Port": 9568, + "Loglevel": 5, + "MaxAgeTime": 7, + "ListenPort": 8000 + }, + { + "ServiceType": "worker", + "Host": "127.0.0.1", + "Port": 9569, + "Loglevel": 5, + "MaxAgeTime": 7 + } + ] +} \ No newline at end of file diff --git a/comm/gameconfig.go b/comm/gameconfig.go new file mode 100644 index 000000000..27c975ffd --- /dev/null +++ b/comm/gameconfig.go @@ -0,0 +1,32 @@ +package comm + +//游戏区服配置 +type GameConfig struct { + AreaId string //区服id 每个区服id都必须是唯一 + ConsulAddr string //区服Consul + IsCross bool ///是否是跨区区服 + BelongCrossServerId string //所属跨服Id (区服id) 不是跨服区服才有效 + LoaclDB *DBConfig //本地db + CrossDB *DBConfig //跨服db + Services []*ServiceConfig //服务列表 可以配置多个gateway 和多个 worker ,只能有一个mainte +} + +//区服db配置 +type DBConfig struct { + RedisIsCluster bool //redis 是否是集群模式 + RedisAddr string //redis 地址 + RedisPassword string //redis 密码 + RedisDB int32 //redis db + MongodbUrl string //mgondb 地址 + MongodbDatabase string //数据库地址 +} + +//服务配置 +type ServiceConfig struct { + ServiceType string //服务类型:gateway(网关服务),worker(业务服务),mainte(维护服务) + Host string //运行主机ip + Port int32 //监控Prot + Loglevel int32 //日志文件输出级别 + MaxAgeTime int32 //日志文件保存时长 + ListenPort int32 //网关和维护服务 都需要提供http服务 所以需要监听端口 +} diff --git a/modules/battle/fight/attribute/attributenumeric.go b/modules/battle/fight/attribute/attributenumeric.go index d4393f6d3..9137887c2 100644 --- a/modules/battle/fight/attribute/attributenumeric.go +++ b/modules/battle/fight/attribute/attributenumeric.go @@ -45,7 +45,7 @@ func (this *AttributeNumeric) Value() float32 { } func (this *AttributeNumeric) SetBase(value float32) float32 { - this.BaseValue.Set(value) + this.BaseValue.SetFloat(value) this.onChange() return this.BaseValue.Value() } diff --git a/modules/battle/fight/attribute/fixednumeric.go b/modules/battle/fight/attribute/fixednumeric.go index 496f2c7c0..7ec29cc63 100644 --- a/modules/battle/fight/attribute/fixednumeric.go +++ b/modules/battle/fight/attribute/fixednumeric.go @@ -2,7 +2,7 @@ package attribute func NewFixedNumeric(pData float32) FixedNumeric { fixed := FixedNumeric{} - fixed.Set(pData) + fixed.SetFloat(pData) return fixed } @@ -10,17 +10,38 @@ type FixedNumeric struct { baseValue FixedPoint } -func (this FixedNumeric) Set(value float32) float32 { - this.baseValue = NewFixedPoint(value) - return this.baseValue.Scalar() -} func (this FixedNumeric) Fixed() FixedPoint { return this.baseValue } + func (this FixedNumeric) Value() float32 { return this.baseValue.Scalar() } +func (this FixedNumeric) GetValue(pDefault float32) float32 { + if this.Value() != 0 { + return this.Value() + } else { + return pDefault + } +} +func (this FixedNumeric) SetFloat(value float32) float32 { + this.baseValue = NewFixedPoint(value) + return this.baseValue.Scalar() +} +func (this FixedNumeric) Set(value FixedPoint) float32 { + this.baseValue = value + return this.baseValue.Scalar() +} + +/// +/// 增加基本值 +/// +func (this FixedNumeric) Add(value float32) float32 { + this.baseValue.Add(value) + return this.baseValue.Scalar() +} + /// /// 减少基本值 /// diff --git a/modules/battle/fight/attribute/fixedpoint.go b/modules/battle/fight/attribute/fixedpoint.go index d1340d857..5f0385e55 100644 --- a/modules/battle/fight/attribute/fixedpoint.go +++ b/modules/battle/fight/attribute/fixedpoint.go @@ -36,6 +36,12 @@ func (this FixedPoint) ToString() string { return fmt.Sprintf("%f", this.Scalar()) } +/// - +func (this FixedPoint) Add(v float32) { + y := NewFixedPoint(v) + this.rawValue = this.rawValue + y.rawValue +} + /// - func (this FixedPoint) Reduce(v float32) { y := NewFixedPoint(v) diff --git a/modules/battle/fight/attribute/healthpoint.go b/modules/battle/fight/attribute/healthpoint.go index baf3c39d2..261a90ed5 100644 --- a/modules/battle/fight/attribute/healthpoint.go +++ b/modules/battle/fight/attribute/healthpoint.go @@ -36,6 +36,12 @@ type HealthPoint struct { CurrMaxHpAppend *AttributeNumeric } +/// +/// 重置当前生命值为最大值 +/// +func (this *HealthPoint) Reset() { + this.Hp.SetFloat(this.CurrMaxHp.Value()) +} func (this *HealthPoint) Value() int32 { return int32(this.Hp.Value()) } @@ -43,10 +49,35 @@ func (this *HealthPoint) MaxValue() int32 { return int32(this.CurrMaxHp.Value()) } +/// +/// 扣血 +/// +/// func (this *HealthPoint) Minus(value float32) { this.Hp.Minus(value) } +/// +/// 加血 +/// +func (this *HealthPoint) Add(value float32) { + if FixedPoint_Add(this.Hp.Fixed(), NewFixedPoint(value)).rawValue > this.CurrMaxHp.Fixed().rawValue { + this.Reset() + } else { + this.Hp.Add(value) + } +} + +/// +/// 获取治疗溢出值 +/// +func (this *HealthPoint) Overflow(value float32) float32 { + if FixedPoint_Add(this.Hp.Fixed(), NewFixedPoint(value)).rawValue > this.CurrMaxHp.Fixed().rawValue { + return FixedPoint_Divide(FixedPoint_Add(this.Hp.Fixed(), NewFixedPoint(value)), this.CurrMaxHp.Fixed()).Scalar() + } + return 0 +} + /// /// 剩余血量百分比 /// diff --git a/modules/battle/fight/fightrole.go b/modules/battle/fight/fightrole.go index 25a251664..6a895b33b 100644 --- a/modules/battle/fight/fightrole.go +++ b/modules/battle/fight/fightrole.go @@ -6,6 +6,7 @@ import ( cfg "go_dreamfactory/sys/configure/structs" ) +///战斗角色 type FightRole struct { /// /// 战斗实例 @@ -15,7 +16,15 @@ type FightRole struct { /// 角色数据 /// data core.FightRoleData - CurrentHealth attribute.HealthPoint + CurrentHealth *attribute.HealthPoint +} + +func (this *FightRole) Initialize(pData core.FightRoleData) { + // this.data = pData + // this.CurrentHealth = attribute.NewHealthPoint(this.data.Hp) + // this.CurrentHealth.Reset() + // this.data.BuffStore.OwnerRole = this + // this.data.PassiveStore.OwnerRole = this } /// @@ -28,7 +37,7 @@ func (this *FightRole) ReceiveDamage(DamageValue float32) { //有不死buff生命值设置为1 for _, v := range this.data.BuffStore.HasBuffTypes { if v == cfg.GameBuffType_UNDEAD { - this.CurrentHealth.Hp.Set(1) + this.CurrentHealth.Hp.SetFloat(1) break } } diff --git a/services/cmd/main.go b/services/cmd/main.go new file mode 100644 index 000000000..3bf8481d3 --- /dev/null +++ b/services/cmd/main.go @@ -0,0 +1,176 @@ +package main + +import ( + "encoding/json" + "flag" + "fmt" + "go_dreamfactory/comm" + "go_dreamfactory/lego/core" + "go_dreamfactory/lego/sys/log" + "io/ioutil" + "os" + "os/exec" + + "gopkg.in/yaml.v3" +) + +/* + 服务类型:区服启动程序 + 服务描述:通过读取游戏json配置,启动服务程序 +*/ +var ( + gmpath = flag.String("p", "./gm.json", "区服配置json") //启动服务的Id +) + +func main() { + flag.Parse() + if err := log.OnInit(nil, + log.SetFileName("./log/cmd.log"), + log.SetLoglevel(log.DebugLevel), + log.SetIsDebug(true)); err != nil { + panic(fmt.Sprintf("Sys log Init err:%v", err)) + } else { + log.Infof("Sys log Init success !") + } + if config, err := readergmconf(*gmpath); err != nil { + log.Error("读取区服配置失败!", log.Field{Key: "err", Value: err}) + } else { + for i, v := range config.Services { + if sseting, err := convertServiceSttings(config, i, v); err != nil { + log.Error("转换服务配置异常!", log.Field{Key: "v", Value: v}, log.Field{Key: "err", Value: err}) + return + } else { + if err = writeServiceConfig(fmt.Sprintf("./conf/%s.yaml", sseting.Id), sseting); err != nil { + log.Error("写入服务配置失败!", log.Field{Key: "sseting", Value: sseting}, log.Field{Key: "err", Value: err}) + return + } + startService(sseting) + } + } + } +} + +//读取游戏配置文件 +func readergmconf(path string) (config *comm.GameConfig, err error) { + config = &comm.GameConfig{} + var ( + jsonFile *os.File + byteValue []byte + ) + if jsonFile, err = os.Open(path); err != nil { + return + } else { + defer jsonFile.Close() + if byteValue, err = ioutil.ReadAll(jsonFile); err != nil { + return + } + err = json.Unmarshal(byteValue, config) + } + return +} + +//转换游戏服务配置 +func convertServiceSttings(config *comm.GameConfig, id int, sconfig *comm.ServiceConfig) (sseting *core.ServiceSttings, err error) { + sseting = &core.ServiceSttings{} + sseting.Modules = make(map[string]map[string]interface{}) + sseting.Sys = make(map[string]map[string]interface{}) + sseting.Sys["rpcx"] = map[string]interface{}{ + "ConsulServers": config.ConsulAddr, + } + switch sconfig.ServiceType { + case comm.Service_Gateway: //网关服务 + sseting.Type = comm.Service_Gateway + sseting.Sys["rpcx"]["RpcxStartType"] = 1 + sseting.Modules["gateway"] = map[string]interface{}{ + "ListenPort": sconfig.ListenPort, + "SpanServiceTag": config.BelongCrossServerId, + } + break + case comm.Service_Worker: //业务服务 + sseting.Type = comm.Service_Worker + sseting.Sys["rpcx"]["RpcxStartType"] = 0 + break + case comm.Service_Mainte: //维护服务 + sseting.Type = comm.Service_Mainte + sseting.Sys["rpcx"]["RpcxStartType"] = 0 + sseting.Modules["web"] = map[string]interface{}{ + "WebDir": "./dist", + "Port": sconfig.ListenPort, + "Key": "@234%67g12q4*67m12#4l67!", + } + break + default: + err = fmt.Errorf("服务类型异常 stype:%s", sseting.Type) + return + } + sseting.Id = fmt.Sprintf("%s_s%d", config.AreaId, id) + sseting.Tag = config.AreaId + sseting.Ip = sconfig.Host + sseting.Port = int(sconfig.Port) + + sseting.Sys["log"] = map[string]interface{}{ + "FileName": fmt.Sprintf("./log/%s.log", sseting.Id), + "Loglevel": sconfig.Loglevel, + "MaxAgeTime": sconfig.MaxAgeTime, + } + sseting.Sys["configure"] = map[string]interface{}{ + "ConfigurePath": "./json", + } + sseting.Sys["db"] = map[string]interface{}{} + sseting.Sys["db"]["Loacl"] = map[string]interface{}{ + "Enabled": true, + "RedisIsCluster": config.LoaclDB.RedisIsCluster, + "RedisAddr": config.LoaclDB.RedisAddr, + "RedisPassword": config.LoaclDB.RedisPassword, + "RedisDB": config.LoaclDB.RedisDB, + "MongodbUrl": config.LoaclDB.MongodbUrl, + "MongodbDatabase": config.LoaclDB.MongodbDatabase, + } + if !config.IsCross { //不是跨服区服务 需要配置所属跨服db + sseting.Sys["db"]["Cross"] = map[string]interface{}{ + "Enabled": true, + "RedisIsCluster": config.CrossDB.RedisIsCluster, + "RedisAddr": config.CrossDB.RedisAddr, + "RedisPassword": config.CrossDB.RedisPassword, + "RedisDB": config.CrossDB.RedisDB, + "MongodbUrl": config.CrossDB.MongodbUrl, + "MongodbDatabase": config.CrossDB.MongodbDatabase, + } + } + + return +} + +//启动服务程序 +func startService(sseting *core.ServiceSttings) (err error) { + var ( + cmd *exec.Cmd + ) + switch sseting.Type { + case comm.Service_Gateway: //网关服务 + cmd = exec.Command("./stup.sh", "start", sseting.Id, "gateway", fmt.Sprintf("./conf/%s.yaml", sseting.Id)) + break + case comm.Service_Worker: //业务服务 + cmd = exec.Command("./stup.sh", "start", sseting.Id, "worker", fmt.Sprintf("./conf/%s.yaml", sseting.Id)) + break + case comm.Service_Mainte: //维护服务 + cmd = exec.Command("./stup.sh", "start", sseting.Id, "mainte", fmt.Sprintf("./conf/%s.yaml", sseting.Id)) + break + default: + err = fmt.Errorf("服务类型异常 stype:%s", sseting.Type) + return + } + err = cmd.Start() + return +} + +//写入服务配置文件 +func writeServiceConfig(filename string, sseting *core.ServiceSttings) (err error) { + var data []byte + if data, err = yaml.Marshal(sseting); err != nil { + return + } else { + err = ioutil.WriteFile(filename, data, 0777) + } + return +}