//----------------------------------------------- HUB start func HubStart() { // start logger config := cfg.Get() if config["hub_log"] != "" { cfg.StartLogger(config["hub_log"]) } log.Println("Starting HUB") startup_work() go SignalProc() // Listen service := DEFAULT_SERVICE if config["hub_service"] != "" { service = config["hub_service"] } log.Println("Hub Service:", service) tcpAddr, err := net.ResolveTCPAddr("tcp4", service) checkError(err) listener, err := net.ListenTCP("tcp", tcpAddr) checkError(err) log.Println("HUB Server OK.") for { conn, err := listener.AcceptTCP() if err != nil { continue } helper.SetConnParam(conn) go handleClient(conn) } }
func Start() { config := cfg.Get() if config["gate_port"] == "" || config["gate_ip"] == "" || config["gate_intra_port"] == "" || config["gate_intra_ip"] == "" { fmt.Println("Gate port/ip or Gate intra_port/intra_ip config nil.") } addr := config["gate_ip"] + ":" + config["gate_port"] intraAddr := config["gate_intra_ip"] + ":" + config["gate_intra_port"] fmt.Println("Gate start listen(intra):", intraAddr) err, intraServer := servernet.NewServer(intraAddr, false) // 内部服务器 if err != nil { fmt.Printf("Listen(intra) fail:", err) } fmt.Println("Gate start listen(extra):", addr) err, extraServer := servernet.NewServer(addr, true) // 外部服务器 if err != nil { fmt.Printf("Listen(internet) fail:", err) } go SignalProc() gsGateInit() gateLoop(intraServer, extraServer) }
//----------------------------------------------- handle cooldown request func handleClient(conn *net.UDPConn) { // init receive buffer config := cfg.Get() maxchan, e := strconv.Atoi(config["stats_max_queue_size"]) if e != nil { maxchan = DEFAULT_MAX_QUEUE log.Println("cannot parse stats_max_queue_size from config", e) } ch := make(chan []byte, maxchan) defer close(ch) go StatsAgent(ch, conn) // loop receiving for { // udp receive buffer, max 512 packet data := make([]byte, 512) n, addr, err := conn.ReadFromUDP(data) if err != nil { log.Println("read udp failed", n, addr, err) continue } ch <- data[:n] } }
func _md5(str string) []byte { config := cfg.Get() salted := str + config["salt"] h := md5.New() io.WriteString(h, salted) return h.Sum(nil) }
//------------------------------------------------ pass-in *ptr func Set(collection string, data interface{}) bool { config := cfg.Get() c := Mongo.DB(config["mongo_db"]).C(collection) v := reflect.ValueOf(data).Elem() version := v.FieldByName("Version") if !version.IsValid() { log.Println(`Cannot seriazlie a struct without "Version" Field`) return false } version.SetUint(uint64(version.Interface().(uint32) + 1)) id := v.FieldByName("UserId") if !id.IsValid() { log.Println(`Cannot seriazlie a struct without "UserId" Field`) return false } info, err := c.Upsert(bson.M{"userid": id.Interface().(int32)}, data) if err != nil { log.Println(info, err) return false } return true }
func TestMongo(t *testing.T) { config := cfg.Get() session, err := mgo.Dial(config["mongo_host"]) if err != nil { panic(err) } defer session.Close() // Optional. Switch the session to a monotonic behavior. session.SetMode(mgo.Monotonic, true) c := session.DB("test").C("people") err = c.Insert(&Person{"Ale", "+55 53 8116 9639"}, &Person{"Cla", "+55 53 8402 8510"}) if err != nil { panic(err) } result := Person{} err = c.Find(bson.M{"name": "Ale"}).One(&result) if err != nil { panic(err) } fmt.Println("Phone:", result.Phone) }
//----------------------------------------------- user's timer func timer_work(sess *Session) { if sess.Flag&SESS_LOGGED_IN == 0 { return } // SIGTERM check if atomic.LoadInt32(&SIGTERM) == 1 { sess.Flag |= SESS_KICKED_OUT helper.NOTICE("SIGTERM received, user exits.", sess.User.Id, sess.User.Name) } // limit rate of request per minute config := cfg.Get() rpm_limit, _ := strconv.ParseFloat(config["rpm_limit"], 32) rpm := float64(sess.PacketCount) / float64(time.Now().Unix()-sess.ConnectTime.Unix()) * 60 if rpm > rpm_limit { sess.Flag |= SESS_KICKED_OUT helper.ERR("user RPM too high", sess.User.Id, sess.User.Name, "RPM:", rpm) return } // try save the data _flush_work(sess) }
//----------------------------------------------- connect to hub func DialHub() { RETRY: INFO("Connecting to HUB") config := cfg.Get() addr, err := net.ResolveTCPAddr("tcp", config["hub_service"]) if err != nil { ERR(err, addr) panic("cannot read hub_service from config") } conn, err := net.DialTCP("tcp", nil, addr) if err != nil { ERR("connect to hub failed", err, "waiting 5 seconds") time.Sleep(5 * time.Second) goto RETRY } // set parameter conn.SetLinger(-1) _conn = conn go _receiver(_conn) INFO("HUB connected") }
//----------------------------------------------- HUB start func HubStart() { log.Println("Starting HUB") // start db StartDB() // data init startup_work() // Listen service := ":9090" config := cfg.Get() if config["hub_service"] != "" { service = config["hub_service"] } log.Println("Hub Service:", service) tcpAddr, err := net.ResolveTCPAddr("tcp4", service) checkError(err) listener, err := net.ListenTCP("tcp", tcpAddr) checkError(err) for { conn, err := listener.Accept() if err != nil { continue } go handleClient(conn) } }
//----------------------------------------------------------- Reload *.csv func Reload() { _lock.Lock() defer _lock.Unlock() _tables = make(map[string]*Table) pattern := os.Getenv("GOPATH") + "/src/gamedata/data/*.csv" config := cfg.Get() if config["gamedata_dir"] != "" { pattern = config["gamedata_dir"] + "/*.csv" } INFO("Loading GameData From", pattern) files, err := filepath.Glob(pattern) if err != nil { ERR(err) panic(err) } for _, f := range files { file, err := os.Open(f) if err != nil { ERR("error opening file", err) continue } parse(file) file.Close() } log.Printf("\033[042;1m%v CSV(s) Loaded\033[0m\n", len(_tables)) }
//---------------------------------------------------------- pop all message for dest user func PopAll(dest_id int32) []IPCObject { config := cfg.Get() c := Mongo.DB(config["mongo_db"]).C(COLLECTION) var objects []IPCObject // mark delete info, err := c.UpdateAll(bson.M{"destid": dest_id}, bson.M{"$set": bson.M{"markdelete": true}}) if err != nil { log.Println(err, info) } // select err = c.Find(bson.M{"destid": dest_id, "markdelete": true}).Sort("-time").All(&objects) if err != nil { log.Println(err) } // real delete info, err = c.RemoveAll(bson.M{"destid": dest_id, "markdelete": true}) if err != nil { log.Println(err, info) } return objects }
//----------------------------------------------- Stats Server start func main() { defer func() { if x := recover(); x != nil { log.Println("caught panic in main()", x) } }() config := cfg.Get() // start logger if config["stats_log"] != "" { cfg.StartLogger(config["stats_log"]) } log.Println("Starting Stats Server") go SignalProc() go SysRoutine() // Listen service := DEFAULT_SERVICE if config["stats_service"] != "" { service = config["stats_service"] } log.Println("Stats Service:", service) udpAddr, err := net.ResolveUDPAddr("udp", service) checkError(err) udpconn, err := net.ListenUDP("udp", udpAddr) checkError(err) log.Println("Stats Server OK.") handleClient(udpconn) }
func stats_sender() { _accum_buffer := make(map[string]map[string]int32) _update_buffer := make(map[string]map[string]string) stats_timer := make(chan int32, 100) stats_timer <- 1 for { select { case req := <-AccumQueue: if _, ok := _accum_buffer[req.F_lang]; !ok { val := make(map[string]int32) val[req.F_key] = 0 _accum_buffer[req.F_lang] = val } val := _accum_buffer[req.F_lang] val[req.F_key] += req.F_value _accum_buffer[req.F_lang] = val case req := <-UpdateQueue: if _, ok := _update_buffer[req.F_lang]; !ok { val := make(map[string]string) val[req.F_key] = "" _update_buffer[req.F_lang] = val } val := _update_buffer[req.F_lang] val[req.F_key] = req.F_value _update_buffer[req.F_lang] = val case <-stats_timer: INFO("Stats Buffer:", len(_accum_buffer), len(_update_buffer)) // 累计 accum := SET_ADDS_REQ{} for accum.F_lang, _ = range _accum_buffer { for accum.F_key, accum.F_value = range _accum_buffer[accum.F_lang] { Send(packet.Pack(Code["set_adds_req"], &accum, nil)) } } _accum_buffer = make(map[string]map[string]int32) // 更新 update := SET_UPDATE_REQ{} for update.F_lang, _ = range _update_buffer { for update.F_key, update.F_value = range _update_buffer[update.F_lang] { Send(packet.Pack(Code["set_update_req"], &update, nil)) } } _update_buffer = make(map[string]map[string]string) // FINI config := cfg.Get() period := STATS_COLLECT_PERIOD if config["stats_collect_period"] != "" { period, _ = strconv.Atoi(config["stats_collect_period"]) } timer.Add(0, time.Now().Unix()+int64(period), stats_timer) runtime.GC() } } }
//---------------------------------------------------------- Load JSON From GameData Directory func LoadJSON(filename string) ([]byte, error) { prefix := os.Getenv("GOPATH") + "/src/gamedata/data" config := cfg.Get() if config["gamedata_dir"] != "" { prefix = config["gamedata_dir"] } path := prefix + "/" + filename return ioutil.ReadFile(path) }
func (s *Samples) Init() { config := cfg.Get() samples, err := strconv.Atoi(config["samples"]) if err != nil { log.Println("cannot parse samples from config", err) samples = DEFAULT_SAMPLES } s.G = gaussian.NewDist(samples) }
func welcome() { fmt.Println("Start gameserver ...") misc.SayHi() //cfg.AllIni() config := cfg.Get() //fmt.Printf("config.ini %v \n", config) fmt.Printf("Author : %v \n", config["author"]) fmt.Printf("Start Date : %v \n", config["date"]) fmt.Printf("Mail : %v \n", config["mail"]) }
func init() { config := cfg.Get() session, err := mgo.Dial(config["mongo_host_stats"]) if err != nil { panic(err) } session.SetMode(mgo.Monotonic, true) _session = session }
func init() { _BUFSIZE = 65535 config := cfg.Get() if config["write_buffer"] != "" { v, _ := strconv.Atoi(config["write_buffer"]) _BUFSIZE = int32(v) } _MAXCHAN = _BUFSIZE / 16 }
//------------------------------------------------ pass-in *ptr or **ptr func Get(collection string, user_id int32, data interface{}) bool { config := cfg.Get() c := Mongo.DB(config["mongo_db"]).C(collection) err := c.Find(bson.M{"userid": user_id}).One(data) if err != nil { log.Println(err, collection, user_id) return false } return true }
//------------------------------------------------ pass-in *[]slice func GetAll(collection string, all interface{}) bool { config := cfg.Get() c := Mongo.DB(config["mongo_db"]).C(collection) err := c.Find(nil).All(all) if err != nil { log.Println(err, collection) return false } return true }
//---------------------------------------------------------- get all events func GetAll() []Event { config := cfg.Get() c := Mongo.DB(config["mongo_db"]).C(COLLECTION) var events []Event err := c.Find(nil).All(&events) if err != nil { log.Println(err) } return events }
//---------------------------------------------------------- remove an event func Remove(event_id int32) bool { config := cfg.Get() c := Mongo.DB(config["mongo_db"]).C(COLLECTION) err := c.Remove(bson.M{"eventid": event_id}) if err != nil { log.Println(err, event_id) return false } return true }
func Add(event *Event) bool { config := cfg.Get() c := Mongo.DB(config["mongo_db"]).C(COLLECTION) err := c.Insert(event) if err != nil { log.Println(err, event) return false } return true }
//------------------------------------------------ data flush control (interval + dirty flag) func _flush_work(sess *Session) { config := cfg.Get() fi := config["flush_interval"] inter, _ := strconv.Atoi(fi) fo := config["flush_ops"] ops, _ := strconv.Atoi(fo) if sess.DirtyCount() > int32(ops) || (sess.DirtyCount() > 0 && time.Now().Unix()-sess.User.LastSaveTime > int64(inter)) { helper.NOTICE("flush dirtycount:", sess.DirtyCount(), "duration(sec):", time.Now().Unix()-sess.User.LastSaveTime) _flush(sess) } }
//---------------------------------------------------------- update a user func Set(user *User) bool { config := cfg.Get() c := Mongo.DB(config["mongo_db"]).C(COLLECTION) info, err := c.Upsert(bson.M{"id": user.Id}, user) if err != nil { log.Println(info, err) return false } return true }
func init() { config := cfg.Get() // dial mongodb sess, err := mgo.Dial(config["mongo_host"]) if err != nil { ERR("cannot connect to", config["mongo_host"], err) os.Exit(-1) } // set default session mode to strong for saving player's data sess.SetMode(mgo.Strong, true) _global_ms = sess }
func init() { config := cfg.Get() // dial mongodb sess, err := mgo.Dial(config["mongo_host_stats"]) if err != nil { ERR(err) os.Exit(-1) } // set default session mode to eventual sess.SetMode(mgo.Eventual, true) _stats_db = sess }
//---------------------------------------------------------- load a user func Get(id int32) *User { config := cfg.Get() c := Mongo.DB(config["mongo_db"]).C(COLLECTION) user := &User{} err := c.Find(bson.M{"id": id}).One(user) if err != nil { log.Println(err, id) return nil } return user }
//---------------------------------------------------------- get an event func Get(event_id int32) *Event { config := cfg.Get() c := Mongo.DB(config["mongo_db"]).C(COLLECTION) event := &Event{} err := c.Find(bson.M{"eventid": event_id}).One(event) if err != nil { log.Println(err, event_id) return nil } return event }
//---------------------------------------------------------- push an ipc object to db func Push(req *IPCObject) bool { config := cfg.Get() c := Mongo.DB(config["mongo_db"]).C(COLLECTION) req.MarkDelete = false err := c.Insert(req) if err != nil { log.Println(err, req) return false } return true }