func (c *Command) Execute(message []byte) { if !c.connection.GetServerAuthState() { return } var commandDetector CommandDetector json.Unmarshal(message, &commandDetector) var isLock bool = false userUUID, err := gocql.ParseUUID(commandDetector.UserUUID) if err != nil { } else { user, err := model_user.Get(userUUID) logger.String(fmt.Sprintf("commandDetector.UserUUID %+v, user %+v", commandDetector.UserUUID, user)) if err == nil && user != nil && user.IsLock { isLock = true } } b, _ := json.Marshal(map[string]interface{}{ "command": "answer", "command_id": commandDetector.CommandId, "is_lock": isLock, }) c.connection.Send(string(b)) }
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 (d *Dispatcher) TurnOn(PlanetUUID *gocql.UUID, BuildingUUID *gocql.UUID) { logger.String("Dispatcher.TurnOn") worker := d.getFreeWorker() m := WorkerMessage{Type: MT_TurnOn, PlanetUUID: PlanetUUID, Params: make(map[string]interface{})} m.Params["*building_uuid"] = BuildingUUID worker.C <- m }
func termHandler(sig os.Signal) error { logger.String(fmt.Sprintf("terminating...")) time.Sleep(time.Second) stop <- struct{}{} if sig == syscall.SIGQUIT { <-done } return daemon.ErrStop }
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 (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 timeWrapper(commandName string, command command.Command, message []byte) { t := time.Now().UnixNano() // t := time.Now() command.Execute(message) // d := time.Now().Sub(t) // d := time.Since(t) d := time.Now().UnixNano() - t logger.String(fmt.Sprintf("command '%s' time: %0.5f", commandName, float64(d) / float64(time.Second))) }
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 LoadOrCreateSession(uuid string, remoteAddr string, userAgent string) *Session { s := New() var err error s.UUID, err = gocql.ParseUUID(uuid) if err == nil { s.Load() } if !s.Exists || (len(remoteAddr) > 0 && remoteAddr != s.RemoteAddr) || userAgent != s.UserAgent { logger.String(fmt.Sprintf("remoteAddr %s %s, userAgent %s %s", remoteAddr, s.RemoteAddr, userAgent, s.UserAgent)) s.Create(remoteAddr, userAgent) } return s }
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 reloadHandler(sig os.Signal) error { logger.String(fmt.Sprintf("configuration reloaded")) return nil }
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 (w *Worker) Loop() { for { mo := <-w.C m := &mo // todo: lock planet planet, _ := model_live_planet.Get(*m.PlanetUUID) lockPlanet(planet) // logger.String(fmt.Sprintf("%+v", m)) switch m.Type { case MT_Build: w.MT_BuildProc(planet, m) case MT_TurnOn: logger.String(fmt.Sprintf("TurnOnTime: %v", time.Now().UnixNano())) buildingUUID := m.Params["*building_uuid"].(*gocql.UUID) building, _ := model_building.Get(*buildingUUID) building.Update(model2.Fields{ "TurnOnTime": time.Now().UnixNano(), }) case MT_Treat: ptt := planet.TreatTime / 1000000000 ctt := time.Now().UnixNano() / 1000000000 for ptt < ctt { conn := planet.GetConnection() att := planet.TreatTime + 1000000000 // check for build queue for len(planet.QueueBuildType) > 0 { btype := planet.QueueBuildType[0] x := planet.QueueBuildX[0] y := planet.QueueBuildY[0] i1 := EnergyStation["levelParams"].([]interface{}) i2 := i1[0].(map[string]interface{}) i3 := i2["level_up"] i4 := i3.(map[string]interface{}) costMinerals := i4["minerals"].(int) costCrystals := i4["crystals"].(int) duration := i4["time"].(int) population := i4["pop"].(int) building, _ := model_building.Create() building.Update(model2.Fields{ "Type": btype, "Level": 0, "TurnOn": false, "TurnOnTime": 0, "X": x, "Y": y, "UpgradeInProgress": true, "UpgradeDuration": duration, "UpgradeElapsed": 0, "UpgradePopulation": population, }) planet.Update(model2.Fields{ "Minerals": planet.Minerals - float64(costMinerals), "Crystals": planet.Crystals - float64(costCrystals), "PopulationAvail": planet.PopulationAvail - float64(population), "Buildings": append(planet.Buildings, building.UUID), "QueueBuildType": planet.QueueBuildType[1:], "QueueBuildX": planet.QueueBuildX[1:], "QueueBuildY": planet.QueueBuildY[1:], "BuildInProgress": append(planet.BuildInProgress, building.UUID), }) conn := planet.GetConnection() if conn != nil { conn.Send(building.NCBuildingUpdate(m.PlanetUUID)) conn.Send(planet.NCUpdatePlanetResources()) } } again := true for len(planet.BuildInProgress) > 0 && again { again = false for i, UUID := range planet.BuildInProgress { building, _ := model_building.Get(UUID) if building == nil { continue } building.Update(model2.Fields{ "UpgradeElapsed": building.UpgradeElapsed + 1, }) if building.UpgradeElapsed >= building.UpgradeDuration { population := building.UpgradePopulation if building.Level == 0 { building.Update(model2.Fields{ "Level": 1, "UpgradeInProgress": false, "UpgradeElapsed": 0, "UpgradeDuration": 0, "UpgradePopulation": 0, "TurnOnTime": time.Now().UnixNano(), }) } planet.Update(model2.Fields{ "BuildInProgress": append(planet.BuildInProgress[:i], planet.BuildInProgress[i+1:]...), "PopulationAvail": planet.PopulationAvail + float64(population), "TurnOnBuildings": append(planet.TurnOnBuildings, building.UUID), }) if conn != nil { conn.Send(building.NCBuildingUpdate(m.PlanetUUID)) conn.Send(planet.NCUpdatePlanetResources()) } again = true break } else { if conn != nil { conn.Send(building.NCBuildingUpdate(m.PlanetUUID)) } } } } // 1. check turn on buildings again = true for len(planet.TurnOnBuildings) > 0 && again { again = false for i, UUID := range planet.TurnOnBuildings { building, _ := model_building.Get(UUID) if building.TurnOnTime < att { levelInfo := GetBuildingLevelInfo(building.Type, building.Level) popUsage, energyUsage := GetBuildingUsage(levelInfo) avail := false if popUsage <= planet.PopulationAvail && energyUsage <= planet.EnergyAvail { avail = true } if avail { building.Update(model2.Fields{ "TurnOn": true, "TurnOnTime": 0, }) planet.Update(model2.Fields{ "TurnOnBuildings": append(planet.TurnOnBuildings[:i], planet.TurnOnBuildings[i+1:]...), "PopulationAvail": planet.PopulationAvail - float64(popUsage), "EnergyAvail": planet.EnergyAvail - float64(energyUsage), }) // custom building logic Treators[building.Type].TurnOn(building, planet) if conn != nil { conn.Send(building.NCBuildingUpdate(m.PlanetUUID)) conn.Send(planet.NCUpdatePlanetResources()) } again = true break } else { // send problem turn on } } } } // custom work th := &TreatHint{UpdateResource: false} for _, UUID := range planet.Buildings { building, _ := model_building.Get(UUID) if building == nil || !building.TurnOn { continue } t, ok := Treators[building.Type] if ok { t.TreatSecond(building, planet, th) } } if th.UpdateResource && conn != nil { conn.Send(planet.NCUpdatePlanetResources()) } planet.Update(model2.Fields{ "TreatTime": planet.TreatTime + 1000000000, }) ptt = planet.TreatTime / 1000000000 } // logger.String(fmt.Sprintf("treat planet %s", m.PlanetUUID.String())) } // todo: unlock planet unlockPlanet(planet) } }
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 (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 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 }
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 *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 (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 }