package model import ( "github.com/gin-gonic/gin" "gopkg.in/yaml.v2" "io/ioutil" "os" "rocommon/util" "sort" "strconv" "strings" "sync" ) ///0 serverlist ///1 inner server ///2 outer server ///https://blog.51cto.com/xingej/2115258 配置文件内容 var serviceConfig *ServerListNode = nil type ServerListNode struct { configLock sync.RWMutex //#白名单列表 ServerList []*ServerNode `yaml:"serverlist,flow"` WhiteList WhiteListNode `yaml:"whitelist"` BlackList WhiteListNode `yaml:"blacklist"` BlackPlatformList []string `yaml:"blackplatformlist"` serverNormalList []*ServerNode //正常外网服务器 serverMapList map[int]*ServerNode serverSpeList []*ServerNode //type特殊类型服务器1-20 configPath string fileInfo os.FileInfo } //State 0正常使用 1维护中 type ServerNode struct { ServerId int `yaml:serverid` ServerName string `yaml:servername` Ip string `yaml:ip` Port []int `yaml:port,flow` Type int `yaml:type` STime string `yaml:stime` State int `yaml:state` Invisible int `yaml:invisible` STimeStamp uint64 } type WhiteListNode struct { Ip []string `yaml:"ip"` Openid []string `yaml:"openid"` ServerList *ServerNode `yaml:"serverlist"` ShenheVersion []string `yaml:"shenheversion"` } type AllServerSt struct { ServerList []ServerNode ServerNum int Page int MaxServerId int } func newServerListNode(path string) *ServerListNode { serviceConfig := &ServerListNode{ configPath: path, serverMapList: map[int]*ServerNode{}, } return serviceConfig } var sessionIdGen int64 = 0 func (this *ServerListNode) GetServerById(c *gin.Context, nodeId string) *ServerNode { serverId, err := strconv.Atoi(nodeId) if err != nil { return nil } tmpConfig := GetServiceConfig() ip := c.ClientIP() resver := c.DefaultQuery("resver", "") ///default "" bBlack := tmpConfig.IsBlackList("", ip, resver) //黑名单只看到特殊的IP列表 if bBlack { if tmpConfig.BlackList.ServerList != nil { return tmpConfig.BlackList.ServerList } return nil } subplatform := c.DefaultQuery("sub_platform", "") ///default 0 bBlockPlatform := tmpConfig.IsPlatformBlackList(subplatform) bWhite := tmpConfig.IsWhiteList("", ip, resver) var retServerNode ServerNode for idx := 0; idx < len(this.serverSpeList); idx++ { if this.serverSpeList[idx].ServerId == serverId { if bWhite { retServerNode = *this.serverSpeList[idx] //白名单玩家状态修改 //5维护 6待测试 if retServerNode.State != 6 { retServerNode.State = 0 } } else { retServerNode = *this.serverSpeList[idx] } break } } if serverNode, ok := this.serverMapList[serverId]; ok { if bWhite { retServerNode = *serverNode //白名单玩家状态修改 //5维护 6待测试 if retServerNode.State != 6 { retServerNode.State = 0 } } else { retServerNode = *serverNode } } if bBlockPlatform { retServerNode.State = 5 } if retServerNode.ServerId > 0 { return &retServerNode } return nil } func (this *ServerListNode) GetLatestServer(bForce bool) *ServerNode { if len(this.serverNormalList) > 0 { if bForce { return this.serverNormalList[len(this.serverNormalList)-1] } else { normalListLen := len(this.serverNormalList) for idx := normalListLen - 1; idx >= 0; idx-- { if this.serverNormalList[idx].Invisible > 0 { continue } return this.serverNormalList[idx] } } } return nil } func (this *ServerListNode) IsWhiteList(openId, ip, shenheversion string) bool { for idx := 0; idx < len(this.WhiteList.Ip); idx++ { if this.WhiteList.Ip[idx] == ip { return true } } for idx := 0; idx < len(this.WhiteList.Openid); idx++ { if this.WhiteList.Openid[idx] == openId { return true } } return false } func (this *ServerListNode) IsPlatformBlackList(subplatform string) bool { if subplatform == "" { return false } for idx := 0; idx < len(GetServiceConfig().BlackPlatformList); idx++ { if subplatform == GetServiceConfig().BlackPlatformList[idx] { return true } } return false } func (this *ServerListNode) IsBlackList(openId, ip, shenheversion string) bool { for idx := 0; idx < len(this.BlackList.Ip); idx++ { if strings.Contains(ip, this.BlackList.Ip[idx]) { return true } } for idx := 0; idx < len(this.BlackList.Openid); idx++ { if this.WhiteList.Openid[idx] == openId { return true } } for idx := 0; idx < len(this.BlackList.ShenheVersion); idx++ { if this.BlackList.ShenheVersion[idx] == shenheversion { return true } } return false } func (this *ServerListNode) GetServerList(c *gin.Context, pageIdStr string) interface{} { pageId, err := strconv.Atoi(pageIdStr) if err != nil { return nil } var allServerSt AllServerSt allServerSt.Page = 10 ip := c.ClientIP() resver := c.DefaultQuery("resver", "") ///default "" openId := c.DefaultQuery("openid", "") ///default "" platform := c.DefaultQuery("platform", "") ///default "" openId = ConvertPlatform(openId, platform) tmpConfig := GetServiceConfig() bBlack := tmpConfig.IsBlackList(openId, ip, resver) //黑名单只看到特殊的IP列表 if bBlack { allServerSt.ServerNum = 1 if tmpConfig.BlackList.ServerList != nil { tmpNode := *tmpConfig.BlackList.ServerList if tmpNode.ServerId > allServerSt.MaxServerId { allServerSt.MaxServerId = tmpNode.ServerId } allServerSt.ServerList = append(allServerSt.ServerList, tmpNode) } return allServerSt } subplatform := c.DefaultQuery("sub_platform", "") ///default 0 bBlockPlatform := tmpConfig.IsPlatformBlackList(subplatform) bWhite := tmpConfig.IsWhiteList(openId, ip, resver) serverNum := this.GetServerListNum(bWhite) if pageId <= 0 { pageId = serverNum / 10 if serverNum%10 != 0 { pageId += 1 } if pageId <= 0 { pageId = 1 } } eIdx := pageId * 10 sIdx := eIdx - 10 if eIdx > serverNum { eIdx = serverNum } allServerSt.ServerNum = serverNum for idx := sIdx; idx < eIdx; idx++ { tmpNode := *this.serverNormalList[idx] if bWhite { //白名单玩家状态修改 //5维护 6待测试 if tmpNode.State != 6 { tmpNode.State = 0 } } else if bBlockPlatform { tmpNode.State = 5 } if !bWhite && tmpNode.Invisible > 0 { continue } allServerSt.ServerList = append(allServerSt.ServerList, tmpNode) if tmpNode.ServerId > allServerSt.MaxServerId { allServerSt.MaxServerId = tmpNode.ServerId } } allServerSt.MaxServerId = serverNum return allServerSt } func (this *ServerListNode) GetServerListNum(bWhite bool) int { if bWhite { return len(this.serverNormalList) } else { retNum := 0 for idx := 0; idx < len(this.serverNormalList); idx++ { if this.serverNormalList[idx].Invisible <= 0 { retNum++ } } return retNum } } func (this *ServerListNode) loadConfig() { yamlOpenFile, err := os.OpenFile(this.configPath, os.O_RDWR, 0660) if err != nil { util.FatalF("config not exist!!! %v:%v", this.configPath, err) return } defer yamlOpenFile.Close() tmpFileInfo, err1 := yamlOpenFile.Stat() if err1 != nil { util.FatalF("file info invalid!!! %v:%v", this.configPath, err1) return } if this.fileInfo != nil && this.fileInfo.ModTime().Equal(tmpFileInfo.ModTime()) { //util.InfoF("file same do not load again") return } //reset and clear this.fileInfo = tmpFileInfo this.serverNormalList = []*ServerNode{} this.serverNormalList = []*ServerNode{} this.serverSpeList = []*ServerNode{} this.serverMapList = map[int]*ServerNode{} //whitelist this.WhiteList.Ip = this.WhiteList.Ip[:0] this.WhiteList.Openid = this.WhiteList.Openid[:0] yamlFile, err2 := ioutil.ReadAll(yamlOpenFile) if err2 != nil { util.FatalF("load config [%v] err:%v\n", this.configPath, err2) return } err = yaml.Unmarshal(yamlFile, serviceConfig) if err != nil { util.FatalF("unmarshal [%v] err:%v\n", this.configPath, err) return } //serverlist for idx := 0; idx < len(this.ServerList); idx++ { if this.ServerList[idx].STime != "" { tmpSTime := util.GetTimeByStr(this.ServerList[idx].STime) this.ServerList[idx].STimeStamp = uint64(tmpSTime.Unix()) } if this.ServerList[idx].Type > 0 { this.serverSpeList = append(this.serverSpeList, this.ServerList[idx]) } else { this.serverNormalList = append(this.serverNormalList, this.ServerList[idx]) this.serverMapList[this.ServerList[idx].ServerId] = this.ServerList[idx] } } sort.Slice(this.serverNormalList, func(i, j int) bool { return this.serverNormalList[i].ServerId < this.serverNormalList[j].ServerId }) util.InfoF("Server yaml config load success:%v", this.configPath) } func (this *ServerListNode) Save() { yamlOpenFile, err := os.OpenFile(this.configPath, os.O_RDWR, 0660) if err != nil { util.FatalF("config not exist!!! %v:%v", this.configPath, err) return } defer yamlOpenFile.Close() datas, err := yaml.Marshal(serviceConfig) if err != nil { return } err = ioutil.WriteFile(this.configPath, datas, 0660) if err != nil { util.FatalF("save yaml config path=%v err=%v", this.configPath, err) return } } func InitConfig(configPath string) { if configPath == "" && serviceConfig == nil { return } if serviceConfig == nil { serviceConfig = newServerListNode(configPath) } serviceConfig.loadConfig() } func GetServiceConfig() *ServerListNode { InitConfig("") return serviceConfig }