func (c *Connection) Reading() { c.ws.SetReadLimit(MaxMessageSize) c.ws.SetReadDeadline(time.Now().Add(PongWait)) for { _, message, err := c.ws.ReadMessage() if err != nil { if err != io.EOF && err.Error() != "websocket: close 1005 " { logger.Error(errors.New(err)) } break } smessage := string(message) if smessage == `{"command":"ping"}` { c.Send(`{"command":"pong"}`) continue } else { logger.String(fmt.Sprintf("message: %v", smessage)) } commandDetector := CommandDetector{} err = json.Unmarshal(message, &commandDetector) if err != nil { logger.Error(errors.New(err)) continue } generator, ok := c.commands[commandDetector.Command] if ok { command := generator(c, c.commandContext) go timeWrapper(commandDetector.Command, command, message) } } if c.SessionExists { if c.Session.IsAuth { user, _ := model2_user.Get(c.Session.UserUUID) if user != nil { user.Unlock() } } c.Session.Unlock() } }
func Get(UUID gocql.UUID) *Server { s := &Server{UUID: UUID, Exists: false} var row = map[string]interface{}{} var uuid = UUID.String() if err := CQLSession.Query(`SELECT * FROM servers where server_uuid = ?`, uuid).MapScan(row); err != nil { if err != gocql.ErrNotFound { logger.Error(errors.New(err)) } return s } s.Exists = true s.IP = row["ip"].(string) s.Port = uint16(row["port"].(int)) t := time.Now().Unix() if t-row["live_ts"].(int64) > 10 { s.Exists = false } return s }
func readConfig() (*module_config.Config, *errors.Error) { data, err := ioutil.ReadFile("config.json") if err != nil { return &defaultConfig, errors.New(err) } err = json.Unmarshal(data, &defaultConfig) if err != nil { return &defaultConfig, errors.New(err) } var localConfig string = "local.config.json" mode := "search" for _, arg := range os.Args { if arg[0] == '-' { mode = arg continue } switch mode { case "-localConfig": localConfig = arg mode = "search" } } fmt.Printf("use local config: %s\n", localConfig) data, err = ioutil.ReadFile(localConfig) if err == nil { err = json.Unmarshal(data, &defaultConfig) if err != nil { return &defaultConfig, errors.New(err) } } return &defaultConfig, nil }
func (u *Fields) AddMethod(method string, unique string) error { methodUUID := GetMethodUUID(method, unique) if err := CQLSession.Query(`insert into idx_users_method_uuid (method, method_uuid, user_uuid) values (?,?,?)`, method, methodUUID, u.UUID).Exec(); err != nil { logger.Error(errors.New(err)) return err } return nil }
func (s *Server) Reading() { s.ws.SetReadLimit(MaxMessageSize) s.ws.SetReadDeadline(time.Now().Add(PongWait)) // s.ws.SetPongHandler(func(string) error { s.ws.SetReadDeadline(time.Now().Add(PongWait)); return nil }) for { _, message, err := s.ws.ReadMessage() if err != nil { if err != io.EOF { logger.Error(errors.New(err)) } break } // logger.String(fmt.Sprintf("star message type %d", mt)) smessage := string(message) if smessage != `{"command":"pong"}` { logger.String(fmt.Sprintf("star message: %v", smessage)) } commandDetector := CommandDetector{} err = json.Unmarshal(message, &commandDetector) if err != nil { logger.Error(errors.New(err)) continue } if commandDetector.Command == "answer" { answer, ok := answers[int(commandDetector.CommandId)] if ok { answer <- message delete(answers, int(commandDetector.CommandId)) } } s.ws.SetReadDeadline(time.Now().Add(PongWait)) } }
func Error(err *errors.Error) { var s = err.ErrorWithStack("generated") + errors.New(nil, 3).ErrorWithStack("dropped") lines := strings.Split(s, "\n") s = "" prefix := timePrefix() for _, line := range lines { s += prefix + line + "\n" } f_stderr.Write([]byte(s)) }
func (f *Factory) connectionsTreator() { pingTicker := time.NewTicker(connection.PingPeriod) defer func() { pingTicker.Stop() }() for { select { case message := <-f.writeChannel: logger.String("send message: " + message.Message) go func() { err := message.Connection.Write(websocket.TextMessage, []byte(message.Message)) if err != nil { logger.Error(errors.New(err)) message.Connection.Close() } }() case c := <-f.closeChannel: delete(f.connections, c.Id) case <-pingTicker.C: var cs map[uint32]*connection.Connection = make(map[uint32]*connection.Connection) logger.String("pingTicker.lock") f.mutex.Lock() for index, connection := range f.connections { cs[index] = connection } f.mutex.Unlock() logger.String("pingTicker.unlock") for _, connection := range f.connections { go func() { err := connection.Ping() if err != nil { connection.Close() } }() } // case <-f.closeFactory: } } }
func GetByMethod(method string, unique string) (*Fields, error) { methodUUID := GetMethodUUID(method, unique) u := &Fields{} var row = model.Fields{} if err := CQLSession.Query(`SELECT * FROM idx_users_method_uuid where method = ? and method_uuid = ?`, method, methodUUID).MapScan(row); err != nil { if err != gocql.ErrNotFound { logger.Error(errors.New(err)) } return u, nil } u.UUID = row["user_uuid"].(gocql.UUID) err := u.Load() return u, err }
func (s *Server) Send(message map[string]interface{}) ([]byte, error) { b, err := json.Marshal(message) if err != nil { logger.Error(errors.New(err)) return nil, err } logger.String(fmt.Sprintf("star send: %+v", string(b))) if s.isLocal { command := message["command"].(string) logger.String(fmt.Sprintf("isLocal: %s", command)) generator, ok := commands[command] if ok { command := generator(localConnection, commandContext) command.Execute(b) a := localAnswers[message["command_id"].(int)] delete(localAnswers, message["command_id"].(int)) return a, nil } return nil, nil } s.ws.SetWriteDeadline(time.Now().Add(10 * time.Second)) rc := make(chan []byte) answers[message["command_id"].(int)] = rc err = s.ws.WriteMessage(websocket.TextMessage, b) if err != nil { return nil, err } ri := <-rc return ri, nil }
func Create() (*Fields, error) { var err error m := &Fields{Exists: false} for { m.UUID, err = gocql.RandomUUID() if err != nil { return nil, err } var row = map[string]interface{}{} var apply bool if apply, err = CQLSession.Query(`insert into live_planets (planet_uuid,create_time) values (?,now()) if not exists`, m.UUID).MapScanCAS(row); err != nil { logger.Error(errors.New(err)) return nil, err } if apply { break } } return m, nil }
func (l *LocalConnection) Send(message string) { logger.String(fmt.Sprintf("local send: %+v", message)) commandDetector := CommandDetector{} err := json.Unmarshal([]byte(message), &commandDetector) if err != nil { logger.Error(errors.New(err)) return } logger.String(fmt.Sprintf("local send 1 %+v", commandDetector)) if commandDetector.Command == "answer" { logger.String(fmt.Sprintf("local send 2 %+v", commandDetector.CommandId)) localAnswers[int(commandDetector.CommandId)] = []byte(message) } }
func (s *Server) Pinger() { pingTicker := time.NewTicker(PingPeriod) defer func() { pingTicker.Stop() }() for { select { case <-pingTicker.C: s.ws.SetWriteDeadline(time.Now().Add(WriteWait)) if err := s.ws.WriteMessage(websocket.TextMessage, []byte(`{"command":"ping"}`)); err != nil { logger.Error(errors.New(err)) break } } } }
func (p *Player) Create() error { p.Exists = false for { p.UUID = gocql.TimeUUID() var row = map[string]interface{}{} var apply bool var err error if apply, err = CQLSession.Query(`insert into players (player_uuid,create_time) values (?,now()) if not exists`, p.UUID).MapScanCAS(row); err != nil { logger.Error(errors.New(err)) return err } if apply { break } } return nil }
func (s *Session) Create(remoteAddr string, userAgent string) { s.Exists = false for { s.UUID = gocql.TimeUUID() var row = model.Fields{} var apply bool var err error if apply, err = CQLSession.Query(`insert into auth_sessions (session_uuid,last_access,create_time, remote_addr, user_agent) values (?,now(),now(),?,?) if not exists`, s.UUID, remoteAddr, userAgent).MapScanCAS(row); err != nil { logger.Error(errors.New(err)) return } if apply { break } } s.Load() }
func (m *Fields) Update(fields model.Fields) error { pairs := []string{} for key, value := range fields { switch key { case "UUID": switch value.(type) { case nil: m.UUID = gocql.UUID{} default: m.UUID = value.(gocql.UUID) } case "IsLock": switch value.(type) { case nil: m.IsLock = false default: m.IsLock = value.(bool) } case "LockServerUUID": switch value.(type) { case nil: m.LockServerUUID = gocql.UUID{} default: m.LockServerUUID = value.(gocql.UUID) } case "PlayerUUID": switch value.(type) { case nil: m.PlayerUUID = gocql.UUID{} default: m.PlayerUUID = value.(gocql.UUID) } case "Buildings": m.Buildings = value.([]gocql.UUID) case "Population": switch t := value.(type) { case int: m.Population = float64(t) default: m.Population = value.(float64) } case "PopulationSInc": switch t := value.(type) { case int: m.PopulationSInc = float64(t) default: m.PopulationSInc = value.(float64) } case "PopulationUsage": switch t := value.(type) { case int: m.PopulationUsage = float64(t) default: m.PopulationUsage = value.(float64) } case "PopulationAvail": switch t := value.(type) { case int: m.PopulationAvail = float64(t) default: m.PopulationAvail = value.(float64) } case "Energy": switch t := value.(type) { case int: m.Energy = float64(t) default: m.Energy = value.(float64) } case "EnergyAvail": switch t := value.(type) { case int: m.EnergyAvail = float64(t) default: m.EnergyAvail = value.(float64) } case "Crystals": switch t := value.(type) { case int: m.Crystals = float64(t) default: m.Crystals = value.(float64) } case "CrystalsSInc": switch t := value.(type) { case int: m.CrystalsSInc = float64(t) default: m.CrystalsSInc = value.(float64) } case "Minerals": switch t := value.(type) { case int: m.Minerals = float64(t) default: m.Minerals = value.(float64) } case "MineralsSInc": switch t := value.(type) { case int: m.MineralsSInc = float64(t) default: m.MineralsSInc = value.(float64) } case "TreatTime": switch t := value.(type) { case int: m.TreatTime = int64(t) default: m.TreatTime = value.(int64) } case "QueueBuildType": m.QueueBuildType = value.([]string) case "QueueBuildX": m.QueueBuildX = value.([]int) case "QueueBuildY": m.QueueBuildY = value.([]int) case "BuildInProgress": m.BuildInProgress = value.([]gocql.UUID) case "TurnOnBuildings": m.TurnOnBuildings = value.([]gocql.UUID) } var pair = Field2CQL[key] + "=" switch t := value.(type) { case nil: pair += "null" case bool: pair += fmt.Sprintf("%v", t) case int: pair += fmt.Sprintf("%v", t) case string: pair += "'" + t + "'" case float64: pair += fmt.Sprintf("%v", t) case int64: pair += fmt.Sprintf("%v", t) case *gocql.UUID: pair += t.String() case []*gocql.UUID: a := []string{} for _, uuid := range t { a = append(a, uuid.String()) } pair += "[" + strings.Join(a, ",") + "]" case []gocql.UUID: a := []string{} for _, uuid := range t { a = append(a, uuid.String()) } pair += "[" + strings.Join(a, ",") + "]" case []string: a := []string{} for _, s := range t { a = append(a, `'`+s+`'`) } pair += "[" + strings.Join(a, ",") + "]" case []int: a := []string{} for _, i := range t { a = append(a, strconv.Itoa(i)) } pair += "[" + strings.Join(a, ",") + "]" case gocql.UUID: pair += t.String() default: logger.Error(errors.New(fmt.Sprintf("unknown type: %+v", t))) } pairs = append(pairs, pair) } q := "update live_planets set " + strings.Join(pairs, ",") + " where planet_uuid = " + m.UUID.String() logger.String(q) if err := CQLSession.Query(q).Exec(); err != nil { logger.Error(errors.New(err)) return err } return nil }
func main() { log.SetFlags(log.Llongfile) expvar.Publish("Goroutines", expvar.Func(goroutines)) runtime.GOMAXPROCS(6) var err *errors.Error config, err = readConfig() if err != nil { // logger.Error(fmt.Sprintf("readConfig - %v", err)) log.Fatal(err) // log.Fatal("ListenAndServe: ", err) os.Exit(0) } logger.Init(config.Logger.Path) if config.Daemonize { flag.Parse() daemon.AddCommand(daemon.StringFlag(signal, "quit"), syscall.SIGQUIT, termHandler) daemon.AddCommand(daemon.StringFlag(signal, "stop"), syscall.SIGTERM, termHandler) daemon.AddCommand(daemon.StringFlag(signal, "reload"), syscall.SIGHUP, reloadHandler) cntxt := &daemon.Context{ PidFileName: config.PidFilepath, PidFilePerm: 0644, LogFileName: config.Logger.Path + "/stdout.log", LogFilePerm: 0640, WorkDir: "./", Umask: 027, Args: []string{"[spacecraft-online]"}, } if len(daemon.ActiveFlags()) > 0 { d, err := cntxt.Search() if err != nil { log.Fatalln("Unable send signal to the daemon:", err) } daemon.SendCommands(d) return } d, err := cntxt.Reborn() if err != nil { log.Fatalln(err) } if d != nil { return } defer cntxt.Release() } logger.String(fmt.Sprintf("started")) cluster := gocql.NewCluster(config.Cassandra.IP) cluster.Keyspace = "sc_2" cluster.Consistency = 1 session, berr := cluster.CreateSession() model_server.Init(session) ip, t := localIP() if t != nil { logger.Error(errors.New(t)) os.Exit(0) } server := model_server.New(ip, config.Http.Port) model.Init(server.UUID, session) server.StartUpdater() star.SetLocalServer(server) bdispatcher := buildings.NewDispatcher(config.Buildings.PoolSize) model2.InstallModels(session, server.UUID, model2_auth_session.InstallInfo, model2_user.InstallInfo, model2_live_planet.InstallInfo, model2_building.InstallInfo, model2_player.InstallInfo) var connectionFactory = factory.New() // clients commands connectionFactory.InstallCommand("auth", cmd_auth.Generator) connectionFactory.InstallCommand("logout", cmd_logout.Generator) connectionFactory.InstallCommand("set_section", cmd_set_section.Generator) connectionFactory.InstallCommand("start", cmd_start.Generator) connectionFactory.InstallCommand("get_planet", cmd_get_planet.Generator) connectionFactory.InstallCommand("get_planet_buildings_for_construct", cmd_get_planet_buildings_for_construct.Generator) connectionFactory.InstallCommand("build", cmd_build.Generator) // star commands connectionFactory.InstallCommand("get_session_lock_state", cmd_session_lock_state.Generator) connectionFactory.InstallCommand("get_user_lock_state", cmd_user_lock_state.Generator) connectionFactory.InstallCommand("star_user_logout", cmd_user_logout.Generator) commandContext := &command.Context{Factory: connectionFactory, CQLSession: session, Config: config, ServerUUID: server.UUID, BDispatcher: bdispatcher} star.SetCommands(connectionFactory.GetCommands(), commandContext) http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { logger.String("/ws") if r.Method != "GET" { http.Error(w, "Method not allowed", 405) return } ws, err := connection.Upgrader.Upgrade(w, r, nil) if err != nil { logger.Error(errors.New(err)) return } ra := r.RemoteAddr[:strings.Index(r.RemoteAddr, ":")] c := connectionFactory.CreateConnection(ws, commandContext, ra, r.Header["User-Agent"][0]) // logger.String(ra) // logger.String(r.Header["User-Agent"][0]) logger.String(fmt.Sprintf("accept connection %v", c.Id)) // go c.Writing() c.Reading() c.Close() logger.String(fmt.Sprintf("close connection %v", c.Id)) }) http.HandleFunc("/debug", func(w http.ResponseWriter, r *http.Request) { b, err := json.Marshal(connectionFactory.MakeDebugInfo()) if err != nil { logger.Error(errors.New(err)) } io.WriteString(w, string(b)) }) http.HandleFunc("/api/auth/success", func(w http.ResponseWriter, r *http.Request) { logger.String("/api/auth/success") /* ra := r.RemoteAddr[:strings.Index(r.RemoteAddr, ":")] logger.String("remoteAdder " + ra) logger.String(fmt.Sprintf("%+v", r.Header)) */ client := &http.Client{} req, err := http.NewRequest("GET", "http://auth.spacecraft-online.org/api/check_token?token="+r.URL.Query().Get("token"), nil) if err != nil { logger.Error(errors.New(err)) return } resp, err := client.Do(req) if err != nil { logger.Error(errors.New(err)) return } body, err := ioutil.ReadAll(resp.Body) if err != nil { logger.Error(errors.New(err)) return } if string(body) != "{\"status\":\"ok\",\"result\":true}" { logger.String(string(body)) http.Redirect(w, r, "/", http.StatusMovedPermanently) // logger.Error(errors.New(err)) return } // logger.String(string(body)) sessionUUID, err := gocql.ParseUUID(r.URL.Query().Get("session_uuid")) if err != nil { http.Redirect(w, r, "/", http.StatusMovedPermanently) return } session, err := model2_auth_session.Get(sessionUUID) if err != nil || session == nil { http.Redirect(w, r, "/", http.StatusMovedPermanently) return } // session := model_auth_session.LoadOrCreateSession(session_uuid, "", r.Header["User-Agent"][0]) method := r.URL.Query().Get("method") unique := r.URL.Query().Get("unique") user, _ := model2_user.GetByMethod(method, unique) if session.IsAuth { // check for another user and relogin if user.Exists && user.UUID.String() != session.UserUUID.String() { user.AddMethod(method, unique) } else { } } else { // loging if !user.Exists { user, _ = model2_user.Create() user.Update(model2.Fields{ "Name": r.URL.Query().Get("username"), }) user.AddMethod(method, unique) } } session.Update(model2.Fields{ "IsAuth": true, "UserUUID": user.UUID, "AuthMethod": method, }) http.Redirect(w, r, "/", http.StatusMovedPermanently) }) listen := fmt.Sprintf(":%v", config.Http.Port) logger.String(fmt.Sprintf("listen http %v", listen)) berr = http.ListenAndServe(listen, nil) if berr != nil { // logger.Error(fmt.Sprintf("ListenAndServe - %v", err)) logger.Error(errors.New(berr)) // log.Fatal("ListenAndServe: ", err) os.Exit(0) } go worker() derr := daemon.ServeSignals() if derr != nil { log.Println("Error:", derr) } // log.Println("daemon terminated") logger.String(fmt.Sprintf("daemon terminated")) }
func (m *Model) Load() error { var row = Fields{} m.Exists = false if err := CQLSession.Query(`SELECT * FROM `+m.TableName+` where `+m.UUIDFieldName+` = ?`, m.UUID).MapScan(row); err != nil { if err != gocql.ErrNotFound { logger.Error(errors.New(err)) return err } return nil } logger.String(fmt.Sprintf("%+v", row)) m.IsLock = row["lock"].(bool) m.LockServerUUID = row["lock_server_uuid"].(gocql.UUID) // m.Child.LoadFromMap(row) modelInfo := getModelInfo(m.Child) val := r.Indirect(r.ValueOf(m.Child)) for key, value := range row { var structField r.Value if info, ok := modelInfo.CQLFields[key]; ok { structField = val.Field(info.Num) switch value.(type) { case nil: structField.Set(r.ValueOf(info.Zero)) case []gocql.UUID: switch info.Zero.(type) { case []*gocql.UUID: v := value.([]gocql.UUID) res := []*gocql.UUID{} for _, item := range v { res = append(res, &item) } structField.Set(r.ValueOf(res)) default: structField.Set(r.ValueOf(value)) } case gocql.UUID: logger.String(fmt.Sprintf("value gocql.UUID for key %s ", key)) switch info.Zero.(type) { case *gocql.UUID: logger.String(fmt.Sprintf("assign *gocql.UUID")) v := value.(gocql.UUID) if v.String() == "00000000-0000-0000-0000-000000000000" { // structField.Set(r.ValueOf(nil)) structField.Set(r.ValueOf(info.Zero)) } else { structField.Set(r.ValueOf(&v)) } default: structField.Set(r.ValueOf(value)) } default: structField.Set(r.ValueOf(value)) } // structField.Set(r.ValueOf(value)) } } // logger.String(fmt.Sprintf("%+v", m.Child)) m.Exists = true return nil }
func (m *Fields) Update(fields model.Fields) error { pairs := []string{} for key, value := range fields { switch key { case "UUID": switch value.(type) { case nil: m.UUID = gocql.UUID{} default: m.UUID = value.(gocql.UUID) } case "IsLock": switch value.(type) { case nil: m.IsLock = false default: m.IsLock = value.(bool) } case "LockServerUUID": switch value.(type) { case nil: m.LockServerUUID = gocql.UUID{} default: m.LockServerUUID = value.(gocql.UUID) } case "Name": switch value.(type) { case nil: m.Name = "" default: m.Name = value.(string) } case "SectionName": switch value.(type) { case nil: m.SectionName = "" default: m.SectionName = value.(string) } case "PlayerUUID": switch t := value.(type) { case nil: m.PlayerUUID = nil case gocql.UUID: m.PlayerUUID = &t default: m.PlayerUUID = value.(*gocql.UUID) } } var pair = Field2CQL[key] + "=" switch t := value.(type) { case nil: pair += "null" case bool: pair += fmt.Sprintf("%v", t) case int: pair += fmt.Sprintf("%v", t) case string: pair += "'" + t + "'" case float64: pair += fmt.Sprintf("%v", t) case int64: pair += fmt.Sprintf("%v", t) case *gocql.UUID: pair += t.String() case []*gocql.UUID: a := []string{} for _, uuid := range t { a = append(a, uuid.String()) } pair += "[" + strings.Join(a, ",") + "]" case []gocql.UUID: a := []string{} for _, uuid := range t { a = append(a, uuid.String()) } pair += "[" + strings.Join(a, ",") + "]" case []string: a := []string{} for _, s := range t { a = append(a, `'`+s+`'`) } pair += "[" + strings.Join(a, ",") + "]" case []int: a := []string{} for _, i := range t { a = append(a, strconv.Itoa(i)) } pair += "[" + strings.Join(a, ",") + "]" case gocql.UUID: pair += t.String() default: logger.Error(errors.New(fmt.Sprintf("unknown type: %+v", t))) } pairs = append(pairs, pair) } q := "update users set " + strings.Join(pairs, ",") + " where user_uuid = " + m.UUID.String() logger.String(q) if err := CQLSession.Query(q).Exec(); err != nil { logger.Error(errors.New(err)) return err } return nil }
func (c *Command) Execute(message []byte) { var commandDetector CommandDetector json.Unmarshal(message, &commandDetector) // inner connection auth if commandDetector.ServerUUID != nil { ServerUUID, _ := gocql.ParseUUID(*commandDetector.ServerUUID) // todo: check err server := model_server.Get(ServerUUID) answer := "error" if server.Exists && c.connection.GetRemoteAddr() == server.IP { c.connection.SetServerAuthState() answer = "ok" } c.connection.Send(`{"command":"` + answer + `"}`) return } // --------------- var session *model2_auth_session.Fields sessionUUID, err := gocql.ParseUUID(commandDetector.SessionUUID) if err == nil { session, err = model2_auth_session.Load(sessionUUID) if session != nil { if session.Exists { if session.RemoteAddr != c.connection.GetRemoteAddr() || session.UserAgent != c.connection.GetUserAgent() { session = nil } } else { session = nil } } } if err != nil || session == nil { session, err = model2_auth_session.Create() session.Update(model2.Fields{ "RemoteAddr": c.connection.GetRemoteAddr(), "UserAgent": c.connection.GetUserAgent(), }) } if session.IsLock { b, err := star.Send(session.LockServerUUID, model.Fields{ "command": "get_session_lock_state", "session_uuid": session.UUID, }) var commandCheckSessionDetector CommandCheckSessionDetector if err == nil { json.Unmarshal(b, &commandCheckSessionDetector) } if err != nil || commandCheckSessionDetector.IsLock { // session.Create(c.connection.GetRemoteAddr(), c.connection.GetUserAgent()) session, err = model2_auth_session.Create() session.Update(model2.Fields{ "RemoteAddr": c.connection.GetRemoteAddr(), "UserAgent": c.connection.GetUserAgent(), }) } logger.String(string(b)) } // session.Lock() c.connection.SetSession(session) sendCommandAuth := SendCommandAuth{ Command: "auth", SessionUUID: session.UUID.String(), AuthMethods: c.ctx.Config.Auth.Methods, IsAuth: session.IsAuth, PlayerExists: false, } if session.IsAuth { /* user := model2_user.New() user.UUID = session.UserUUID user.Load() */ user, _ := model2_user.Load(session.UserUUID) logger.String(fmt.Sprintf("user: %+v", user)) // check for user lock if user.IsLock { b, err := star.Send(user.LockServerUUID, model.Fields{ "command": "get_user_lock_state", "user_uuid": user.UUID.String(), }) if err != nil { } else { type CommandCheckUserDetector struct { IsLock bool `json:"is_lock"` } var commandCheckUserDetector CommandCheckUserDetector json.Unmarshal(b, &commandCheckUserDetector) if commandCheckUserDetector.IsLock { _, _ = star.Send(user.LockServerUUID, model.Fields{ "command": "star_user_logout", "user_uuid": user.UUID, "session_uuid": session.UUID.String(), }) user.Load() } } } // user.Lock() if user.PlayerUUID != nil { sendCommandAuth.PlayerExists = true } sendCommandAuth.User = SendCommandAuthUser{ Name: user.Name, SectionName: user.SectionName, } } b, err := json.Marshal(sendCommandAuth) if err != nil { logger.Error(errors.New(err)) return } c.connection.Send(string(b)) }
func (m *Fields) Update(fields model.Fields) error { pairs := []string{} for key, value := range fields { switch key { case "UUID": switch value.(type) { case nil: m.UUID = gocql.UUID{} default: m.UUID = value.(gocql.UUID) } case "IsLock": switch value.(type) { case nil: m.IsLock = false default: m.IsLock = value.(bool) } case "LockServerUUID": switch value.(type) { case nil: m.LockServerUUID = gocql.UUID{} default: m.LockServerUUID = value.(gocql.UUID) } case "Type": switch value.(type) { case nil: m.Type = "" default: m.Type = value.(string) } case "Level": m.Level = value.(int) case "TurnOn": switch value.(type) { case nil: m.TurnOn = false default: m.TurnOn = value.(bool) } case "TurnOnTime": switch t := value.(type) { case int: m.TurnOnTime = int64(t) default: m.TurnOnTime = value.(int64) } case "X": m.X = value.(int) case "Y": m.Y = value.(int) case "UpgradeInProgress": switch value.(type) { case nil: m.UpgradeInProgress = false default: m.UpgradeInProgress = value.(bool) } case "UpgradePopulation": m.UpgradePopulation = value.(int) case "UpgradeElapsed": m.UpgradeElapsed = value.(int) case "UpgradeDuration": m.UpgradeDuration = value.(int) } var pair = Field2CQL[key] + "=" switch t := value.(type) { case nil: pair += "null" case bool: pair += fmt.Sprintf("%v", t) case int: pair += fmt.Sprintf("%v", t) case string: pair += "'" + t + "'" case float64: pair += fmt.Sprintf("%v", t) case int64: pair += fmt.Sprintf("%v", t) case *gocql.UUID: pair += t.String() case []*gocql.UUID: a := []string{} for _, uuid := range t { a = append(a, uuid.String()) } pair += "[" + strings.Join(a, ",") + "]" case []gocql.UUID: a := []string{} for _, uuid := range t { a = append(a, uuid.String()) } pair += "[" + strings.Join(a, ",") + "]" case []string: a := []string{} for _, s := range t { a = append(a, `'`+s+`'`) } pair += "[" + strings.Join(a, ",") + "]" case []int: a := []string{} for _, i := range t { a = append(a, strconv.Itoa(i)) } pair += "[" + strings.Join(a, ",") + "]" case gocql.UUID: pair += t.String() default: logger.Error(errors.New(fmt.Sprintf("unknown type: %+v", t))) } pairs = append(pairs, pair) } q := "update buildings set " + strings.Join(pairs, ",") + " where building_uuid = " + m.UUID.String() logger.String(q) if err := CQLSession.Query(q).Exec(); err != nil { logger.Error(errors.New(err)) return err } return nil }
func (m *Model) Update(fields Fields) error { pairs := []string{} modelInfo := getModelInfo(m.Child) // m.Child.UpdateFields(fields) val := r.Indirect(r.ValueOf(m.Child)) logger.String(fmt.Sprintf("%+v", modelInfo)) logger.String(fmt.Sprintf("%+v", fields)) for key, value := range fields { var inner bool var innerKey string inner = false innerKey = "none" switch key { case "IsLock": innerKey = "lock" inner = true if value == nil { m.IsLock = false } else { m.IsLock = value.(bool) } case "LockServerUUID": innerKey = "lock_server_uuid" inner = true switch t := value.(type) { case *gocql.UUID: m.LockServerUUID = *t case gocql.UUID: m.LockServerUUID = t } } var structField r.Value var info FieldInfo var ok bool if !inner { if info, ok = modelInfo.ModelFields[key]; ok { structField = val.Field(info.Num) switch value.(type) { case nil: structField.Set(r.ValueOf(info.Zero)) case gocql.UUID: logger.String(fmt.Sprintf("value gocql.UUID for key %s ", key)) switch info.Zero.(type) { case *gocql.UUID: logger.String(fmt.Sprintf("assign *gocql.UUID")) v := value.(gocql.UUID) structField.Set(r.ValueOf(&v)) default: structField.Set(r.ValueOf(value)) } default: structField.Set(r.ValueOf(value)) } } else { continue } } var pair string if inner { pair = innerKey + " = " } else { pair = info.CQLField + " = " } switch t := value.(type) { case nil: pair += "null" case bool: pair += fmt.Sprintf("%v", t) case int: pair += fmt.Sprintf("%v", t) case string: pair += "'" + t + "'" case *gocql.UUID: pair += t.String() case []*gocql.UUID: a := []string{} for _, uuid := range t { a = append(a, uuid.String()) } pair += "[" + strings.Join(a, ",") + "]" case gocql.UUID: pair += t.String() default: logger.Error(errors.New(fmt.Sprintf("unknown type: %+v", t))) } pairs = append(pairs, pair) } q := "update " + m.TableName + " set " + strings.Join(pairs, ",") + " where " + m.UUIDFieldName + " = " + m.UUID.String() logger.String(q) if err := CQLSession.Query(q).Exec(); err != nil { logger.Error(errors.New(err)) return err } // logger.String(fmt.Sprintf("%+v", m.Child)) return nil }
func NewServer(serverUUID gocql.UUID) *Server { s := &Server{isLocal: false} e := model_server.Get(serverUUID) if !e.Exists { logger.String(fmt.Sprintf("server %s not found in storage", serverUUID.String())) return nil } path := fmt.Sprintf("http://%s:%d/ws", e.IP, e.Port) logger.String(fmt.Sprintf("connect to: %s", path)) u, err := url.Parse(path) if err != nil { logger.String(fmt.Sprintf("%v", err)) // return err return nil } rawConn, err := net.Dial("tcp", u.Host) if err != nil { logger.String(fmt.Sprintf("%v", err)) // return err return nil } wsHeaders := http.Header{ "Origin": {"http://local.host:80"}, // your milage may differ "Sec-WebSocket-Extensions": {"permessage-deflate; client_max_window_bits, x-webkit-deflate-frame"}, "User-Agent": {"spacecrfat-agent"}, } wsConn, _, err := websocket.NewClient(rawConn, u, wsHeaders, 4096, 4096) if err != nil { logger.String(fmt.Sprintf("%v", err)) // return fmt.Errorf("websocket.NewClient Error: %s\nResp:%+v", err, resp) return nil } s.ws = wsConn s.ws.SetWriteDeadline(time.Now().Add(10 * time.Second)) err = s.ws.WriteMessage(websocket.TextMessage, []byte(fmt.Sprintf(`{"command":"auth","server_uuid":"%s"}`, localServer.UUID.String()))) if err != nil { logger.String(fmt.Sprintf("%v", err)) return nil } _, message, err := s.ws.ReadMessage() // s.ws.ReadMessage() if err != nil { if err != io.EOF { logger.Error(errors.New(err)) } } smessage := string(message) logger.String(fmt.Sprintf("star auth answer: %v", smessage)) go s.Reading() go s.Pinger() return s }