示例#1
0
文件: lobby.go 项目: demipixel/Helen
func (Lobby) LobbyJoin(server *wsevent.Server, so *wsevent.Client, data []byte) []byte {
	reqerr := chelpers.FilterRequest(so, authority.AuthAction(0), true)

	if reqerr != nil {
		return reqerr.Encode()

	}

	var args struct {
		Id    *uint   `json:"id"`
		Class *string `json:"class"`
		Team  *string `json:"team" valid:"red,blu"`
	}

	if err := chelpers.GetParams(data, &args); err != nil {
		return helpers.NewTPErrorFromError(err).Encode()
	}
	//helpers.Logger.Debug("id %d class %s team %s", *args.Id, *args.Class, *args.Team)

	player, tperr := models.GetPlayerBySteamId(chelpers.GetSteamId(so.Id()))

	if tperr != nil {
		return tperr.Encode()
	}

	lob, tperr := models.GetLobbyById(*args.Id)
	if tperr != nil {
		return tperr.Encode()
	}

	if lob.State == models.LobbyStateEnded {
		return helpers.NewTPError("Cannot join a closed lobby.", -1).Encode()

	}

	//Check if player is in the same lobby
	var sameLobby bool
	if id, err := player.GetLobbyId(); err == nil && id == *args.Id {
		sameLobby = true
	}

	slot, tperr := models.LobbyGetPlayerSlot(lob.Type, *args.Team, *args.Class)
	if tperr != nil {
		return tperr.Encode()

	}

	if prevId, err := player.GetLobbyId(); err != nil {
		server.RemoveClient(so.Id(), fmt.Sprintf("%d_public", prevId))
		server.RemoveClient(so.Id(), fmt.Sprintf("%d_private", prevId))
	}

	tperr = lob.AddPlayer(player, slot, *args.Team, *args.Class)

	if tperr != nil {
		return tperr.Encode()
	}

	if !sameLobby {
		chelpers.AfterLobbyJoin(server, so, lob, player)
	}

	if lob.IsFull() {
		lob.State = models.LobbyStateReadyingUp
		lob.ReadyUpTimestamp = time.Now().Unix() + 30
		lob.Save()

		tick := time.After(time.Second * 30)
		id := lob.ID
		stop := make(chan struct{})

		go func() {
			select {
			case <-tick:
				lobby := &models.Lobby{}
				db.DB.First(lobby, id)

				if lobby.State != models.LobbyStateInProgress {
					err := lobby.RemoveUnreadyPlayers()
					if err != nil {
						helpers.Logger.Error("RemoveUnreadyPlayers: ", err.Error())
						err = nil
					}

					err = lobby.UnreadyAllPlayers()
					if err != nil {
						helpers.Logger.Error("UnreadyAllPlayers: ", err.Error())
					}

					lobby.State = models.LobbyStateWaiting
					lobby.Save()
				}

			case <-stop:
				return
			}
		}()

		room := fmt.Sprintf("%s_private",
			chelpers.GetLobbyRoom(lob.ID))
		broadcaster.SendMessageToRoom(room, "lobbyReadyUp",
			`{"timeout":30}`)
		models.BroadcastLobbyList()
	}

	err := models.AllowPlayer(*args.Id, player.SteamId, *args.Team+*args.Class)
	if err != nil {
		helpers.Logger.Error(err.Error())
	}

	if lob.State == models.LobbyStateInProgress {
		bytes, _ := json.Marshal(models.DecorateLobbyConnect(lob, player.Name, *args.Class))
		broadcaster.SendMessage(player.SteamId, "lobbyStart", string(bytes))
	}

	return chelpers.EmptySuccessJS
}
示例#2
0
func LobbyJoin(so socketio.Socket) func(string) string {
	return chelpers.FilterRequest(so, lobbyJoinFilters,
		func(params map[string]interface{}) string {
			player, tperr := models.GetPlayerBySteamId(chelpers.GetSteamId(so.Id()))

			if tperr != nil {
				bytes, _ := tperr.ErrorJSON().Encode()
				return string(bytes)
			}

			lobbyid := params["id"].(uint)
			classString := params["class"].(string)
			teamString := params["team"].(string)

			lob, tperr := models.GetLobbyById(uint(lobbyid))
			if tperr != nil {
				bytes, _ := tperr.ErrorJSON().Encode()
				return string(bytes)
			}

			//Check if player is in the same lobby
			var sameLobby bool
			if id, err := player.GetLobbyId(); err == nil && id == lobbyid {
				sameLobby = true
			}

			slot, tperr := models.LobbyGetPlayerSlot(lob.Type, teamString, classString)
			if tperr != nil {
				bytes, _ := tperr.ErrorJSON().Encode()
				return string(bytes)
			}

			helpers.LockRecord(lob.ID, lob)
			defer helpers.UnlockRecord(lob.ID, lob)
			tperr = lob.AddPlayer(player, slot)

			if tperr != nil {
				bytes, _ := tperr.ErrorJSON().Encode()
				return string(bytes)
			}

			if !sameLobby {
				chelpers.AfterLobbyJoin(so, lob, player)
			}

			if lob.IsFull() {
				lob.State = models.LobbyStateReadyingUp
				lob.Save()
				lob.ReadyUpTimeoutCheck()
				room := fmt.Sprintf("%s_private",
					chelpers.GetLobbyRoom(lob.ID))
				broadcaster.SendMessageToRoom(room, "lobbyReadyUp",
					`{"timeout":30}`)
				models.BroadcastLobbyList()
			}

			models.BroadcastLobbyToUser(lob, player.SteamId)
			bytes, _ := chelpers.BuildSuccessJSON(simplejson.New()).Encode()
			return string(bytes)
		})
}