Beispiel #1
0
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))
}
Beispiel #2
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 #3
0
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

}
Beispiel #4
0
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
}
Beispiel #5
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 #6
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 #7
0
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)))
}
Beispiel #8
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 #9
0
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
}
Beispiel #10
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 #11
0
func reloadHandler(sig os.Signal) error {
	logger.String(fmt.Sprintf("configuration reloaded"))
	return nil
}
Beispiel #12
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 #13
0
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)

	}
}
Beispiel #14
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 #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 "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 #16
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 #17
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
}
Beispiel #18
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 #19
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 #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

}