Beispiel #1
0
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()

	}

}
Beispiel #2
0
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
}
Beispiel #3
0
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
}
Beispiel #4
0
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
}
Beispiel #5
0
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))
	}
}
Beispiel #6
0
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))

}
Beispiel #7
0
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:
		}
	}
}
Beispiel #8
0
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
}
Beispiel #9
0
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
}
Beispiel #10
0
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
}
Beispiel #11
0
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)
	}

}
Beispiel #12
0
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
			}
		}
	}
}
Beispiel #13
0
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
}
Beispiel #14
0
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()

}
Beispiel #15
0
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

}
Beispiel #16
0
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"))

}
Beispiel #17
0
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
}
Beispiel #18
0
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

}
Beispiel #19
0
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))
}
Beispiel #20
0
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

}
Beispiel #21
0
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
}
Beispiel #22
0
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
}