package gamecommon import ( "encoding/json" "fmt" "log" _ "math/rand" "os" "time" "sync" slog "bet24.com/log" "bet24.com/utils" ) var Server struct { LogLevel string FileLevel string LogPath string CertFile string KeyFile string MaxConnNum int Login string Password string Database string Datasource string GameDB string ChannelUrl string ChannelPassword string RedisDB int LastHour int ServiceAddr string // ServerName string ServerIP string ServerPort int ServerAddr string MonitorPort int OfflineSeconds int64 } type RobotParam struct { WinAmount int // 输赢金额 Param1 int // 换牌解闷概率 Param2 int // 换牌闷玩家概率 } type RobotConfig struct { MinRobotGold int MaxRobotGold int RobotOnlineSec int RobotCount int MinRoom int Params []RobotParam winAmount int } func (rc *RobotConfig) getParam1() int { for _, v := range rc.Params { if rc.winAmount >= v.WinAmount { return v.Param1 } } return 0 } func (rc *RobotConfig) addWinAmount(amount int) { rc.winAmount += amount } type RoomInfo struct { RoomID int //场次ID, 唯一 RoomName string RoomDesc string MinGold int MaxGold int BaseScore int TaxRate float64 // 税收 PlayMode int //0普通模式,1加倍模式 // ServerIP string ServerPort int IsDual int // 是否2人桌 RobotConfig } type RoomList struct { Rooms []RoomInfo lock *sync.RWMutex } var Rooms *RoomList func (r *RoomList) AddWinAmount(roomId int, amount int) { r.lock.Lock() defer r.lock.Unlock() for i := 0; i < len(r.Rooms); i++ { if r.Rooms[i].RoomID == roomId { r.Rooms[i].addWinAmount(amount) return } } } func (r *RoomList) GetParam1(roomId int) int { r.lock.RLock() defer r.lock.RUnlock() for i := 0; i < len(r.Rooms); i++ { if r.Rooms[i].RoomID == roomId { return r.Rooms[i].getParam1() } } return 0 } func (r *RoomList) Dump() string { r.lock.RLock() defer r.lock.RUnlock() var ret string for _, v := range r.Rooms { ret = fmt.Sprintf("%s Room:%s winAmount:%d\n", ret, v.RoomName, v.winAmount) } return ret } var RoomConfgName = "domino" // func GetRoomInfo() string { // d, _ := json.Marshal(Room) // return string(d) // } func init() { configFile := "domino/server.json" data, err := os.ReadFile(configFile) if err != nil { log.Fatalf("read config failed domino/server.json %v", err) } fmt.Println(string(data)) err = json.Unmarshal(data, &Server) if err != nil { log.Fatalf("Unmarshal config failed domino/server.json err:%v", err) return } logger, err := slog.New(Server.LogLevel, Server.FileLevel, fmt.Sprintf("%v/%v", Server.LogPath, RoomConfgName), log.LstdFlags) if err == nil { slog.Export(logger) } originPort := Server.ServerPort for i := 0; i < 100; i++ { if utils.CheckPortInUse(Server.ServerPort) { Server.ServerPort++ continue } break } if Server.MonitorPort == 0 { Server.MonitorPort = Server.ServerPort + 100 } now := time.Now() Server.LastHour = now.Hour() if originPort != Server.ServerPort { slog.Debug("Port %d in use, change to %d", originPort, Server.ServerPort) d, _ := json.Marshal(Server) os.WriteFile(configFile, d, 0644) } } func Run() { Rooms = new(RoomList) Rooms.lock = &sync.RWMutex{} refreshLogFile() } func refreshLogFile() { time.AfterFunc(5*time.Minute, refreshLogFile) doRefreshLogFile() doRefreshConfig() } func doRefreshLogFile() { if Server.LogPath != "" { now := time.Now() if now.Hour() != Server.LastHour { Server.LastHour = now.Hour() slog.RecreateFileLog(fmt.Sprintf("%v/%v", Server.LogPath, RoomConfgName), log.LstdFlags) } } } func doRefreshConfig() { // 保存 // 加载房间表 data, err := os.ReadFile("domino/rooms.json") //fmt.Println(string(data)) if err != nil { log.Fatal("read rooms failed domino/rooms.json") } Rooms.lock.Lock() defer Rooms.lock.Unlock() /* winMaps := make(map[int]int) for _,v := range Rooms { winMaps[v.RoomID]. } */ err = json.Unmarshal(data, &Rooms) if err != nil { log.Fatalf("Unmarshal rooms failed err:%v", err) return } if len(Rooms.Rooms) <= 0 { log.Fatalf("Rooms.Rooms == 0") return } if len(Server.ServerIP) > 0 { ws := "ws" if len(Server.CertFile) > 0 { ws = "wss" } for i := 0; i < len(Rooms.Rooms); i++ { Rooms.Rooms[i].ServerIP = fmt.Sprintf("%s://%s:%d", ws, Server.ServerIP, Server.ServerPort) } } }