// ConnectPlayer handles connecting a new player to the game func (s *Server) ConnectPlayer(socket *glue.Socket) { // Logging log15.Debug("socket connected", "address", socket.RemoteAddr()) socket.OnClose(func() { log15.Debug("socket closed", "address", socket.RemoteAddr()) }) // Attempt to allocate free player Slot if slot := s.nextSlot(); slot != -1 { log15.Info("Accepting new player connection", "slot", slot) s.ConnectedPlayers[slot] = &Player{ Server: s, Slot: slot, Socket: socket, } s.ConnectedPlayers[slot].Socket.OnClose(func() { log15.Debug("socket closed", "address", socket.RemoteAddr()) s.DisconnectPlayer(slot) }) s.NumConnectedPlayers++ s.ConnectedPlayers[slot].Socket.Write(msg.SConnected) s.ConnectedPlayers[slot].Socket.Write(msg.SDisplayMessage + ":Press [SPACEBAR] To Spawn!") go s.ConnectedPlayers[slot].ReadLoop() } else { // No free slots available log15.Info("Rejecting new player connection: Server is full!") socket.Write(msg.SGameFull) } }
func init() { /* Initialise configuration instance, w/ GABS. */ log.Debug("Initialise configuration instance") // This has to be a absolute path. configurationPath := os.Getenv("RESTAPI_CONFIG") // Ascertain if the configuration path is inputted. log.Debug("Testing if the configuration path is inputted.") if _, err := os.Stat(configurationPath); os.IsNotExist(err) { log.Crit("The configuration file does not exist!", log.Ctx{"File": configurationPath}) os.Exit(1) } log.Debug("Reading configuration file into RAM.") configurationFile, err := ioutil.ReadFile(configurationPath) if err != nil { log.Error("The JSON config could not be loaded..", log.Ctx{"Error": err.Error()}) os.Exit(1) } log.Debug("Parsing configuration file into a GABS instance.") config, err = gabs.ParseJSON(configurationFile) if err != nil { log.Error("The JSON config could not be parsed.", log.Ctx{"Error": err.Error()}) os.Exit(1) } /* Finish initializing the configuration instance */ }
// Turn this gridbike func (gb *GridBike) Turn() { if gb.rot+math.Pi == gb.rotNew || gb.rot-math.Pi == gb.rotNew { log15.Debug("Bike can't turn 180°", "at", gb.pos) gb.rotNew = gb.rot return } log15.Debug("Bike turned", "at", gb.pos) gb.trail.end = gb.pos gb.trail.verts = append(gb.trail.verts, gb.pos) gb.rot = gb.rotNew }
// Simulate runs a frame of simulation func (s *Simulation) Simulate(deltaTime float64) { // Simulate one frame of gridbike movement for i := range s.gridBikes { switch s.gridBikes[i].state { case Move: s.gridBikes[i].Move(deltaTime) case Turn: s.gridBikes[i].Turn() s.gridBikes[i].SetState(Move) s.gridBikes[i].Move(deltaTime) } } // check for collisions for i := range s.gridBikes { if s.gridBikes[i].state == Dead { continue } checkPos := vec2.Add(&s.gridBikes[i].pos, &vec2.T{ math.Cos(s.gridBikes[i].rot) * s.gridBikes[i].speed * deltaTime, math.Sin(s.gridBikes[i].rot) * s.gridBikes[i].speed * deltaTime, }) if collided, with := s.checkCollisions(checkPos); collided { log15.Debug("Bike collision", "with", with, "at", s.gridBikes[i].pos, "collision point", checkPos) s.gridBikes[i].Kill() } } // update json string to send to clients s.updateStateString() }
// SetTurn tells this gridbike to turn on the next update func (gb *GridBike) SetTurn(newRot float64) { if gb.state != Dead { gb.rotNew = newRot gb.SetState(Turn) } else { log15.Debug("not turning dead gridbike!") } }
// SpawnGridBike spawns a new gridbike func (s *Simulation) SpawnGridBike(name string, colour string) *GridBike { pos, rot := s.calcNewSpawnpoint() speed := 120.0 log15.Debug("Spawning bike", "at", pos, "rot", rot, "speed", speed, "name", name, "colour", colour) newGridTrail := &GridTrail{ state: Active, colour: colour, origin: pos, } newGridBike := &GridBike{ state: Move, name: name, colour: colour, pos: pos, rot: rot, speed: speed, rotNew: rot, trail: newGridTrail, simulation: s, } s.gridTrails = append(s.gridTrails, newGridTrail) s.gridBikes = append(s.gridBikes, newGridBike) if s.numActiveBikes == 0 { s.IncreaseNumActiveBikes() go func() { now := time.Now() then := now for s.numActiveBikes > 0 { now = time.Now() s.Simulate(now.Sub(then).Seconds()) then = now } time.Sleep(4 * time.Second) s.updateStateString() }() } else { s.IncreaseNumActiveBikes() } return newGridBike }
// ReadLoop receives data from the player client func (p *Player) ReadLoop() { for { // Wait for available data data, err := p.Socket.Read() if err != nil { // return and release this goroutine if the socket was closed if err == glue.ErrSocketClosed { return } log15.Error("read error", "error", err) continue } components := strings.Split(data, ":") switch components[0] { case msg.CRequestState: p.Socket.Write(msg.SNewState + ":" + p.Server.Sim.LatestState) case msg.CSpawn: if !p.neededComponents(components, 2) { break } if p.Bike != nil && p.Bike.GetState() != "dead" { log15.Debug("Player attempted to spawn with existing bike", "bike", p.Bike) break } p.Bike = p.Server.Sim.SpawnGridBike(components[1], components[2]) p.Socket.Write(msg.SDisplayMessage + ":") case msg.CTurn: if !p.neededComponents(components, 1) { break } if p.Bike == nil || p.Bike.GetState() != "move" { log15.Debug("Player attemped to turn without existing bike", "bike", p.Bike) break } dir := components[1] switch dir { case "RIGHT": p.Bike.SetTurn(0) case "DOWN": p.Bike.SetTurn(math.Pi / 2) case "LEFT": p.Bike.SetTurn(math.Pi) case "UP": p.Bike.SetTurn(3 * math.Pi / 2) default: log15.Error("invalid TURN argument", "arg", dir) } // case msg.CBroadcast: // // Echo the received data to all other clients // for i := range gs.ConnectedPlayers { // if gs.ConnectedPlayers[i].Socket.ID() == p.Socket.ID() { // continue // } // gs.ConnectedPlayers[i].Socket.Write(strings.Join(components[1:], ":")) // } default: log15.Info("Returning unknown request to the client", "request", data) p.Socket.Write(data) } } }
func (c *client) GetAllInto(destination interface { Add(interface{}) error Count() int MaxCreatedAt() time.Time MaxUpdatedAt() time.Time }) (err error) { var response ItembaseResponse DocumentsReceived := 0 err = c.api.Call("GET", c.url, c.auth, nil, c.params, &response) if err != nil { return } for _, document := range response.Documents { if destination.Add != nil { err = destination.Add(document) if err != nil { log.Info("Error when adding document", "error", err) } } } log.Debug("Documents", "found", response.NumDocumentsFound) log.Debug("Documents", "returned", response.NumDocumentsReturned) if response.NumDocumentsFound == response.NumDocumentsReturned { log.Debug("same amount of documents that were found as returned") return } else { DocumentsReceived = response.NumDocumentsReturned TotalDocuments := response.NumDocumentsFound log.Debug("expecting to receive", "NumDocumentsFound", response.NumDocumentsFound) for DocumentsReceived < TotalDocuments { log.Debug("expecting", "TotalDocuments", TotalDocuments) if c.max > 0 { log.Debug("Max", "max", c.max) if DocumentsReceived >= c.max { log.Debug("Max is reached", "DocumentsReceived", DocumentsReceived) return } } if _, ok := c.params["created_at_from"]; ok { if c.params["created_at_from"] == destination.MaxCreatedAt().Format(time.RFC3339) { log.Error("created_at_from equals to previous created_at_from - We got a loop?", "created_at_from", c.params["created_at_from"]) return } } c = c.clientWithNewParam("start_at_document", DocumentsReceived) err = c.api.Call("GET", c.url, c.auth, nil, c.params, &response) if err != nil { log.Error("Error when retrieving paginated results", "error", err) } log.Debug("Documents", "found", response.NumDocumentsFound) log.Debug("Documents", "returned", response.NumDocumentsReturned) if len(response.Documents) == 0 { log.Debug("no documents in response", "response.Documents", len(response.Documents)) return } for _, document := range response.Documents { if destination.Add != nil { destination.Add(document) if err != nil { log.Info("Error when adding document", "error", err) } } } if DocumentsReceived == destination.Count() { log.Error("Same amount of documents in destination interface as before. Can happen due to created_at collission during pagination.") return } log.Debug("Documents", "saved", destination.Count()) DocumentsReceived = destination.Count() if len(response.Documents) == 1 { log.Debug("only 1 document in response", "response.Documents", len(response.Documents)) return } } } return }