Coverage Report
Generated on 13 Feb 16 17:44 +0000 with gocov-html
Package Overview: github.com/TF2Stadium/Helen/models 66.97%

This is a coverage report created after analysis of the github.com/TF2Stadium/Helen/models package. It has been generated with the following command:

gocov test github.com/TF2Stadium/Helen/models | gocov-html

Here are the stats. Please select a function name to view its implementation and see what's left for testing.

LobbySettingsToJSON(...)github.com/TF2Stadium/Helen/models/lobbySettings.go100.00%56/56
Lobby.FitsRequirements(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%13/13
Lobby.Close(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%13/13
Player.GenAuthKey(...)github.com/TF2Stadium/Helen/models/player.go100.00%12/12
Lobby.SubNotInGamePlayers(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%8/8
Player.GetLobbyID(...)github.com/TF2Stadium/Helen/models/player.go100.00%8/8
LobbyGetPlayerSlot(...)github.com/TF2Stadium/Helen/models/classMaps.go100.00%7/7
DeleteUnusedServerRecords(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%7/7
DecorateSubstitute(...)github.com/TF2Stadium/Helen/models/lobby_decorators.go100.00%7/7
DecorateSubstituteList(...)github.com/TF2Stadium/Helen/models/lobby_decorators.go100.00%6/6
Lobby.Save(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%6/6
LobbyGetSlotInfoString(...)github.com/TF2Stadium/Helen/models/classMaps.go100.00%5/5
Player.IsBannedWithTime(...)github.com/TF2Stadium/Helen/models/player.go100.00%5/5
Player.Save(...)github.com/TF2Stadium/Helen/models/player.go100.00%5/5
PlayerStats.IncreaseClassCount(...)github.com/TF2Stadium/Helen/models/playerStats.go100.00%4/4
Player.SetSetting(...)github.com/TF2Stadium/Helen/models/player.go100.00%4/4
Lobby.OnChange(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%4/4
Lobby.Substitute(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%4/4
Player.GenMumbleUsername(...)github.com/TF2Stadium/Helen/models/player.go100.00%4/4
Lobby.HasSlotRequirement(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%3/3
GetRoomMessages(...)github.com/TF2Stadium/Helen/models/chat.go100.00%3/3
Lobby.HasPlayer(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%3/3
NewBotMessage(...)github.com/TF2Stadium/Helen/models/chat.go100.00%3/3
Lobby.GetPlayerSlotObj(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%3/3
GetPlayerMessages(...)github.com/TF2Stadium/Helen/models/chat.go100.00%3/3
Lobby.GetSlotRequirement(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%3/3
Lobby.CurrentState(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%3/3
DecoratePlayerSummary(...)github.com/TF2Stadium/Helen/models/player_decorators.go100.00%3/3
Lobby.GetPlayerIDBySlot(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%3/3
Lobby.FillSubstitute(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%3/3
Lobby.UnreadyAllPlayers(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%3/3
Lobby.setInGameStatus(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%3/3
Lobby.IsEveryoneReady(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%3/3
Lobby.IsPlayerReady(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%3/3
Lobby.Start(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%2/2
Player.BanUntil(...)github.com/TF2Stadium/Helen/models/player.go100.00%2/2
PlayerStats.IncreaseSubCount(...)github.com/TF2Stadium/Helen/models/playerStats.go100.00%2/2
decoratePlayerTags(...)github.com/TF2Stadium/Helen/models/player_decorators.go100.00%2/2
LogCustomAdminAction(...)github.com/TF2Stadium/Helen/models/admin_log.go100.00%2/2
Lobby.SlotNeedsSubstitute(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%2/2
Player.IsBanned(...)github.com/TF2Stadium/Helen/models/player.go100.00%2/2
BroadcastLobby(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%2/2
FumbleLobbyPlayerJoined(...)github.com/TF2Stadium/Helen/models/fumble.go100.00%2/2
SendNotification(...)github.com/TF2Stadium/Helen/models/chat.go100.00%2/2
NewLobby(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%2/2
BroadcastSubList(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%2/2
GetWaitingLobbies(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%2/2
Lobby.BanPlayer(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%2/2
NewPlayerStats(...)github.com/TF2Stadium/Helen/models/playerStats.go100.00%2/2
NewChatMessage(...)github.com/TF2Stadium/Helen/models/chat.go100.00%2/2
Lobby.GetPlayerSlot(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%2/2
Lobby.HasRequirements(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%1/1
ChatMessage.Save(...)github.com/TF2Stadium/Helen/models/chat.go100.00%1/1
Requirement.Save(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%1/1
PlayerStats.TotalLobbies(...)github.com/TF2Stadium/Helen/models/playerStats.go100.00%1/1
Lobby.SetInGame(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%1/1
Player.Unban(...)github.com/TF2Stadium/Helen/models/player.go100.00%1/1
Lobby.SetNotInGame(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%1/1
Lobby.RealAfterSave(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%1/1
BroadcastLobbyList(...)github.com/TF2Stadium/Helen/models/lobby.go100.00%1/1
End(...)github.com/TF2Stadium/Helen/models/pauling.go100.00%1/1
LogAdminAction(...)github.com/TF2Stadium/Helen/models/admin_log.go100.00%1/1
DecorateLobbyLeave(...)github.com/TF2Stadium/Helen/models/lobby_decorators.go100.00%1/1
DecorateLobbyClosed(...)github.com/TF2Stadium/Helen/models/lobby_decorators.go100.00%1/1
DisallowPlayer(...)github.com/TF2Stadium/Helen/models/pauling.go100.00%1/1
DecorateLobbyData(...)github.com/TF2Stadium/Helen/models/lobby_decorators.go96.43%27/28
decorateSlotDetails(...)github.com/TF2Stadium/Helen/models/lobby_decorators.go93.33%14/15
Lobby.RemoveUnreadyPlayers(...)github.com/TF2Stadium/Helen/models/lobby.go92.31%12/13
LoadLobbySettings(...)github.com/TF2Stadium/Helen/models/lobbySettings.go86.67%39/45
fumbleAllowPlayer(...)github.com/TF2Stadium/Helen/models/fumble.go85.71%6/7
Player.GetSetting(...)github.com/TF2Stadium/Helen/models/player.go85.71%6/7
Lobby.UpdateStats(...)github.com/TF2Stadium/Helen/models/lobby.go83.33%10/12
LobbyGetSlotInfo(...)github.com/TF2Stadium/Helen/models/classMaps.go83.33%5/6
Lobby.RemoveSpectator(...)github.com/TF2Stadium/Helen/models/lobby.go83.33%5/6
Lobby.RemovePlayer(...)github.com/TF2Stadium/Helen/models/lobby.go83.33%5/6
GetLobbyByID(...)github.com/TF2Stadium/Helen/models/lobby.go83.33%5/6
GetLobbyByIDServer(...)github.com/TF2Stadium/Helen/models/lobby.go83.33%5/6
LobbyMap.GetFormat(...)github.com/TF2Stadium/Helen/models/lobbySettings.go83.33%5/6
NewPlayer(...)github.com/TF2Stadium/Helen/models/player.go80.00%8/10
Lobby.UnreadyPlayer(...)github.com/TF2Stadium/Helen/models/lobby.go80.00%4/5
Lobby.IsPlayerInGame(...)github.com/TF2Stadium/Helen/models/lobby.go80.00%4/5
Player.GetSpectatingIds(...)github.com/TF2Stadium/Helen/models/player.go80.00%4/5
Player.IsSpectatingID(...)github.com/TF2Stadium/Helen/models/player.go80.00%4/5
Player.GetActiveBans(...)github.com/TF2Stadium/Helen/models/player.go80.00%4/5
Lobby.AddSpectator(...)github.com/TF2Stadium/Helen/models/lobby.go80.00%4/5
Lobby.GetPlayerNumber(...)github.com/TF2Stadium/Helen/models/lobby.go80.00%4/5
GetPlayerWithStats(...)github.com/TF2Stadium/Helen/models/player.go80.00%4/5
GetPlayerBySteamID(...)github.com/TF2Stadium/Helen/models/player.go80.00%4/5
Lobby.ReadyPlayer(...)github.com/TF2Stadium/Helen/models/lobby.go80.00%4/5
GetPlayerByID(...)github.com/TF2Stadium/Helen/models/player.go75.00%3/4
Player.Alias(...)github.com/TF2Stadium/Helen/models/player.go75.00%3/4
FumbleLobbyEnded(...)github.com/TF2Stadium/Helen/models/fumble.go66.67%2/3
GetLobbyFormat(...)github.com/TF2Stadium/Helen/models/lobbySettings.go66.67%2/3
GetLobbyMap(...)github.com/TF2Stadium/Helen/models/lobbySettings.go66.67%2/3
GetLobbyLeague(...)github.com/TF2Stadium/Helen/models/lobbySettings.go66.67%2/3
Lobby.AddPlayer(...)github.com/TF2Stadium/Helen/models/lobby.go65.96%31/47
DecorateLobbyListData(...)github.com/TF2Stadium/Helen/models/lobby_decorators.go60.00%3/5
PlayerStats.PlayedCountIncrease(...)github.com/TF2Stadium/Helen/models/playerStats.go42.86%3/7
getGamemode(...)github.com/TF2Stadium/Helen/models/lobby.go23.08%3/13
Player.UpdatePlayerInfo(...)github.com/TF2Stadium/Helen/models/player.go10.53%2/19
DecoratePlayerProfileJson(...)github.com/TF2Stadium/Helen/models/player_decorators.go0.00%0/18
ConnectRPC(...)github.com/TF2Stadium/Helen/models/rpc.go0.00%0/12
DecorateLobbyConnect(...)github.com/TF2Stadium/Helen/models/lobby_decorators.go0.00%0/12
Player.IsSubscribed(...)github.com/TF2Stadium/Helen/models/player.go0.00%0/12
GetScrollback(...)github.com/TF2Stadium/Helen/models/chat.go0.00%0/10
InitializeLobbySettings(...)github.com/TF2Stadium/Helen/models/lobbySettings.go0.00%0/7
FumbleLobbyCreated(...)github.com/TF2Stadium/Helen/models/fumble.go0.00%0/5
Lobby.IsSlotFilled(...)github.com/TF2Stadium/Helen/models/lobby.go0.00%0/4
LoadLobbySettingsFromFile(...)github.com/TF2Stadium/Helen/models/lobbySettings.go0.00%0/4
Lobby.SetupServer(...)github.com/TF2Stadium/Helen/models/lobby.go0.00%0/4
GetAllActiveBans(...)github.com/TF2Stadium/Helen/models/player.go0.00%0/3
GetLobbyWhitelist(...)github.com/TF2Stadium/Helen/models/lobbySettings.go0.00%0/3
ChatMessage.Send(...)github.com/TF2Stadium/Helen/models/chat.go0.00%0/3
IsPlayerInServer(...)github.com/TF2Stadium/Helen/models/pauling.go0.00%0/3
NewRequirement(...)github.com/TF2Stadium/Helen/models/lobby.go0.00%0/3
serverExists(...)github.com/TF2Stadium/Helen/models/pauling.go0.00%0/2
SetupServer(...)github.com/TF2Stadium/Helen/models/pauling.go0.00%0/2
Lobby.GetAllSlots(...)github.com/TF2Stadium/Helen/models/lobby.go0.00%0/2
Lobby.GetUnreadyPlayers(...)github.com/TF2Stadium/Helen/models/lobby.go0.00%0/2
@759:32(...)github.com/TF2Stadium/Helen/models/lobby.go0.00%0/2
FumbleLobbyPlayerJoinedSub(...)github.com/TF2Stadium/Helen/models/fumble.go0.00%0/2
Lobby.Delete(...)github.com/TF2Stadium/Helen/models/lobby.go0.00%0/2
ReExecConfig(...)github.com/TF2Stadium/Helen/models/pauling.go0.00%0/1
LobbyData.Send(...)github.com/TF2Stadium/Helen/models/lobby_decorators.go0.00%0/1
VerifyInfo(...)github.com/TF2Stadium/Helen/models/pauling.go0.00%0/1
NewInGameChatMessage(...)github.com/TF2Stadium/Helen/models/chat.go0.00%0/1
Lobby.SetState(...)github.com/TF2Stadium/Helen/models/lobby.go0.00%0/1
Say(...)github.com/TF2Stadium/Helen/models/pauling.go0.00%0/1
LobbyData.SendToPlayer(...)github.com/TF2Stadium/Helen/models/lobby_decorators.go0.00%0/1
BroadcastLobbyToUser(...)github.com/TF2Stadium/Helen/models/lobby.go0.00%0/1
Lobby.LobbyData(...)github.com/TF2Stadium/Helen/models/lobby.go0.00%0/1
DecorateLobbyJoin(...)github.com/TF2Stadium/Helen/models/lobby_decorators.go0.00%0/1
Lobby.ReadyUpTimeLeft(...)github.com/TF2Stadium/Helen/models/lobby.go0.00%0/1
Lobby.IsFull(...)github.com/TF2Stadium/Helen/models/lobby.go0.00%0/1
github.com/TF2Stadium/Helen/models66.97%519/775
func LobbySettingsToJSON
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobbySettings.go:

270
func LobbySettingsToJSON() *simplejson.Json {
271
        j := simplejson.New()
272
273
        // formats
274
        {
275
                formats := simplejson.New()
276
277
                formatList := make([]*simplejson.Json, len(LobbyFormats))
278
                for i, format := range LobbyFormats {
279
                        f := simplejson.New()
280
                        f.Set("value", format.Name)
281
                        f.Set("title", format.PrettyName)
282
                        f.Set("important", format.Important)
283
284
                        formatList[i] = f
285
                }
286
                formats.Set("key", "type")
287
                formats.Set("title", "Format")
288
                formats.Set("options", formatList)
289
290
                j.Set("formats", formats)
291
        }
292
293
        // maps
294
        {
295
                maps := simplejson.New()
296
297
                mapList := make([]*simplejson.Json, len(LobbyMaps))
298
                for i, amap := range LobbyMaps {
299
                        f := simplejson.New()
300
                        f.Set("value", amap.Name)
301
                        for _, mapFormat := range amap.Formats {
302
                                f.Set(mapFormat.Format.Name, mapFormat.Importance)
303
                        }
304
305
                        mapList[i] = f
306
                }
307
                maps.Set("key", "mapName")
308
                maps.Set("title", "Map")
309
                maps.Set("options", mapList)
310
311
                j.Set("maps", maps)
312
        }
313
314
        // leagues
315
        {
316
                leagues := simplejson.New()
317
318
                leagueList := make([]*simplejson.Json, len(LobbyLeagues))
319
                for i, league := range LobbyLeagues {
320
                        leagueDescs := simplejson.New()
321
                        for _, leagueDesc := range league.Descriptions {
322
                                leagueDescs.Set(string(leagueDesc.MapType), leagueDesc.Description)
323
                        }
324
325
                        f := simplejson.New()
326
                        f.Set("value", league.Name)
327
                        f.Set("title", league.PrettyName)
328
                        f.Set("descriptions", leagueDescs)
329
                        for _, leagueFormat := range league.Formats {
330
                                f.Set(leagueFormat.Format.Name, leagueFormat.Used)
331
                        }
332
333
                        leagueList[i] = f
334
                }
335
                leagues.Set("key", "league")
336
                leagues.Set("title", "League")
337
                leagues.Set("options", leagueList)
338
339
                j.Set("leagues", leagues)
340
        }
341
342
        // whitelists
343
        {
344
                whitelists := simplejson.New()
345
346
                whitelistList := make([]*simplejson.Json, len(LobbyWhitelists))
347
                for i, whitelist := range LobbyWhitelists {
348
                        f := simplejson.New()
349
                        f.Set("value", whitelist.ID)
350
                        f.Set("title", whitelist.PrettyName)
351
                        f.Set("league", whitelist.League.Name)
352
                        f.Set("format", whitelist.Format.Name)
353
354
                        whitelistList[i] = f
355
                }
356
                whitelists.Set("key", "whitelist")
357
                whitelists.Set("title", "Whitelist")
358
                whitelists.Set("options", whitelistList)
359
360
                j.Set("whitelists", whitelists)
361
        }
362
363
        return j
364
}
func Lobby.FitsRequirements
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

186
func (l *Lobby) FitsRequirements(player *Player, slot int) (bool, *helpers.TPError) {
187
        //BUG(vibhavp): FitsRequirements doesn't check reliability
188
        var req *Requirement
189
190
        slotReq, err := l.GetSlotRequirement(slot)
191
        if err == nil {
192
                req = slotReq
193
        }
194
195
        db.DB.Preload("Stats").First(player, player.ID)
196
197
        if time.Since(player.UpdatedAt) < time.Hour*time.Duration(req.Hours-player.GameHours) {
198
                //update player info only if the number of hours needed > the number of hours
199
                //passed since player info was last updated
200
                player.UpdatePlayerInfo()
201
                player.Save()
202
        }
203
204
        if player.GameHours < req.Hours {
205
                return false, ReqHoursErr
206
        }
207
208
        if player.Stats.TotalLobbies() < req.Lobbies {
209
                return false, ReqLobbiesErr
210
        }
211
212
        return true, nil
213
}
func Lobby.Close
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

683
func (lobby *Lobby) Close(rpc bool) {
684
        db.DB.First(&lobby).UpdateColumn("state", LobbyStateEnded)
685
        db.DB.Table("server_records").Where("id = ?", lobby.ServerInfoID).Delete(&ServerRecord{})
686
        db.DB.Table("requirements").Where("lobby_id = ?", lobby.ID).Delete(&Requirement{})
687
        //db.DB.Exec("DELETE FROM spectators_players_lobbies WHERE lobby_id = ?", lobby.ID)
688
        if rpc {
689
                End(lobby.ID)
690
        }
691
692
        privateRoom := fmt.Sprintf("%d_private", lobby.ID)
693
        broadcaster.SendMessageToRoom(privateRoom, "lobbyLeft", DecorateLobbyLeave(lobby))
694
695
        publicRoom := fmt.Sprintf("%d_public", lobby.ID)
696
        broadcaster.SendMessageToRoom(publicRoom, "lobbyClosed", DecorateLobbyClosed(lobby))
697
698
        BroadcastSubList()
699
        BroadcastLobby(lobby)
700
        BroadcastLobbyList() // has to be done manually for now
701
        FumbleLobbyEnded(lobby)
702
}
func Player.GenAuthKey
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

175
func (player *Player) GenAuthKey() string {
176
        var count int
177
        var authKey string
178
179
        for {
180
                buff := bytes.NewBufferString(player.SteamID)
181
                buff.Grow(32)
182
                rand.Read(buff.Bytes())
183
184
                sum := sha256.Sum256(buff.Bytes())
185
                authKey = hex.EncodeToString(sum[:])
186
187
                db.DB.Table("players").Where("mumble_authkey = ?", authKey).Count(&count)
188
                if count == 0 {
189
                        break
190
                }
191
        }
192
193
        return authKey
194
}
func Lobby.SubNotInGamePlayers
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

743
func (lobby *Lobby) SubNotInGamePlayers() {
744
        playerids := []uint{}
745
        db.DB.Table("lobby_slots").Where("lobby_id = ? AND in_game = ?", lobby.ID, false).Pluck("player_id", &playerids)
746
        db.DB.Table("lobby_slots").Where("lobby_id = ? AND in_game = ? AND needs_sub = ?", lobby.ID, false, false).UpdateColumn("needs_sub", true)
747
748
        for _, id := range playerids {
749
                player, _ := GetPlayerByID(id)
750
                SendNotification(fmt.Sprintf("%s has been reported for not joining the game.", player.Alias()), int(lobby.ID))
751
        }
752
        BroadcastSubList()
753
        return
754
}
func Player.GetLobbyID
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

258
func (player *Player) GetLobbyID(inProgress bool) (uint, *helpers.TPError) {
259
        playerSlot := &LobbySlot{}
260
        states := []LobbyState{LobbyStateEnded}
261
        if inProgress {
262
                states = append(states, LobbyStateInProgress)
263
        }
264
265
        err := db.DB.Joins("INNER JOIN lobbies ON lobbies.id = lobby_slots.lobby_id").
266
                Where("lobby_slots.player_id = ? AND lobbies.state NOT IN (?)", player.ID, states).
267
                First(playerSlot).Error
268
269
        // if the player is not in any lobby or the player has been reported/needs sub, return error
270
        if err != nil || playerSlot.NeedsSub {
271
                return 0, helpers.NewTPError("Player not in any lobby", 1)
272
        }
273
274
        return playerSlot.LobbyID, nil
275
}
func LobbyGetPlayerSlot
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/classMaps.go:

100
func LobbyGetPlayerSlot(lobbytype LobbyType, teamStr string, classStr string) (int, *helpers.TPError) {
101
        team, ok := teamMap[teamStr]
102
        if !ok {
103
                return -1, helpers.NewTPError("Invalid team", -1)
104
        }
105
106
        class, ok := typeClassMap[lobbytype][classStr]
107
        if !ok {
108
                return -1, helpers.NewTPError("Invalid class", -1)
109
        }
110
111
        return team*NumberOfClassesMap[lobbytype] + class, nil
112
}
func DeleteUnusedServerRecords
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

92
func DeleteUnusedServerRecords() {
93
        serverInfoIDs := []uint{}
94
        db.DB.Table("server_records").Pluck("id", &serverInfoIDs)
95
        for _, id := range serverInfoIDs {
96
                lobby := &Lobby{}
97
                err := db.DB.Where("server_info_id = ?", id).First(lobby).Error
98
99
                if err != nil || lobby.State == LobbyStateEnded {
100
                        db.DB.Table("server_records").Where("id = ?", id).Delete(&ServerRecord{})
101
                }
102
        }
103
}
func DecorateSubstitute
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby_decorators.go:

251
func DecorateSubstitute(slot *LobbySlot) SubstituteData {
252
        lobby := &Lobby{}
253
        db.DB.First(lobby, slot.LobbyID)
254
        substitute := SubstituteData{
255
                LobbyID: lobby.ID,
256
                Format:  formatMap[lobby.Type],
257
                MapName: lobby.MapName,
258
                Mumble:  lobby.Mumble,
259
        }
260
261
        substitute.Region.Name = lobby.RegionName
262
        substitute.Region.Code = lobby.RegionCode
263
264
        substitute.Team, substitute.Class, _ = LobbyGetSlotInfoString(lobby.Type, slot.Slot)
265
266
        return substitute
267
}
func DecorateSubstituteList
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby_decorators.go:

269
func DecorateSubstituteList() []SubstituteData {
270
        slots := []*LobbySlot{}
271
        subList := []SubstituteData{}
272
273
        db.DB.Table("lobby_slots").Joins("INNER JOIN lobbies ON lobbies.id = lobby_slots.lobby_id").Where("lobby_slots.needs_sub = ? AND lobbies.state = ?", true, LobbyStateInProgress).Find(&slots)
274
275
        for _, slot := range slots {
276
                subList = append(subList, DecorateSubstitute(slot))
277
        }
278
279
        return subList
280
}
func Lobby.Save
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

321
func (lobby *Lobby) Save() error {
322
        var err error
323
        if db.DB.NewRecord(lobby) {
324
                err = db.DB.Create(lobby).Error
325
        } else {
326
                err = db.DB.Save(lobby).Error
327
        }
328
329
        lobby.RealAfterSave()
330
        return err
331
}
func LobbyGetSlotInfoString
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/classMaps.go:

115
func LobbyGetSlotInfoString(lobbytype LobbyType, slot int) (team, class string, err *helpers.TPError) {
116
        classList := typeClassList[lobbytype]
117
118
        teamI, classI, err := LobbyGetSlotInfo(lobbytype, slot)
119
        if err == nil {
120
                team, class, err = teamList[teamI], classList[classI], nil
121
        }
122
        return
123
}
func Player.IsBannedWithTime
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

363
func (player *Player) IsBannedWithTime(t PlayerBanType) (bool, time.Time) {
364
        ban := &PlayerBan{}
365
        err := db.DB.Where("type = ? AND until > now() AND player_id = ? AND active = TRUE", t, player.ID).
366
                Order("until desc").First(ban).Error
367
        if err != nil {
368
                return false, time.Time{}
369
        }
370
371
        return true, ban.Until
372
}
func Player.Save
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

215
func (player *Player) Save() error {
216
        var err error
217
        if db.DB.NewRecord(player) {
218
                err = db.DB.Create(player).Error
219
        } else {
220
                err = db.DB.Save(player).Error
221
        }
222
        return err
223
}
func PlayerStats.IncreaseClassCount
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/playerStats.go:

63
func (ps *PlayerStats) IncreaseClassCount(lobby *Lobby, slot int) {
64
        _, class, _ := LobbyGetSlotInfoString(lobby.Type, slot)
65
        classes := map[string]*int{
66
                "scout1":   &ps.Scout,
67
                "scout2":   &ps.Scout,
68
                "roamer":   &ps.Soldier,
69
                "pocket":   &ps.Soldier,
70
                "soldier":  &ps.Soldier,
71
                "soldier1": &ps.Soldier,
72
                "soldier2": &ps.Soldier,
73
                "pyro":     &ps.Pyro,
74
                "engineer": &ps.Engineer,
75
                "heavy":    &ps.Heavy,
76
                "demoman":  &ps.Demoman,
77
                "sniper":   &ps.Sniper,
78
                "medic":    &ps.Medic,
79
                "spy":      &ps.Spy,
80
        }
81
82
        *(classes[class])++
83
        database.DB.Save(ps)
84
}
func Player.SetSetting
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

340
func (player *Player) SetSetting(key string, value string) {
341
        if player.Settings == nil {
342
                player.Settings = make(gorm.Hstore)
343
        }
344
345
        player.Settings[key] = &value
346
        player.Save()
347
}
func Lobby.OnChange
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

772
func (lobby *Lobby) OnChange(base bool) {
773
        switch lobby.State {
774
        case LobbyStateWaiting, LobbyStateInProgress, LobbyStateReadyingUp:
775
                BroadcastLobby(lobby)
776
                if base {
777
                        BroadcastLobbyList()
778
                }
779
        }
780
}
func Lobby.Substitute
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

809
func (lobby *Lobby) Substitute(player *Player) {
810
        db.DB.Table("lobby_slots").Where("lobby_id = ? AND player_id = ?", lobby.ID, player.ID).UpdateColumn("needs_sub", true)
811
812
        db.DB.Preload("Stats").First(player, player.ID)
813
        player.Stats.IncreaseSubCount()
814
        BroadcastSubList()
815
}
func Player.GenMumbleUsername
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

196
func (player *Player) GenMumbleUsername() string {
197
        last := &Player{}
198
        db.DB.Table("players").Last(last)
199
200
        mumbleNick := fmt.Sprintf("TF2Stadium%d", last.ID+1)
201
        return mumbleNick
202
}
func Lobby.HasSlotRequirement
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

174
func (lobby *Lobby) HasSlotRequirement(slot int) bool {
175
        var count int
176
        db.DB.Table("requirements").Where("lobby_id = ? AND slot = ?", lobby.ID, slot).Count(&count)
177
        return count != 0
178
}
func GetRoomMessages
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/chat.go:

100
func GetRoomMessages(room int) ([]*ChatMessage, error) {
101
        var messages []*ChatMessage
102
103
        err := db.DB.Table("chat_messages").Where("room = ?", room).Order("created_at").Find(&messages).Error
104
105
        return messages, err
106
}
func Lobby.HasPlayer
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

362
func (lobby *Lobby) HasPlayer(player *Player) bool {
363
        var count int
364
        db.DB.Table("lobby_slots").Where("lobby_id = ? AND player_id = ?", lobby.ID, player.ID).Count(&count)
365
366
        return count != 0
367
}
func NewBotMessage
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/chat.go:

79
func NewBotMessage(message string, room int) *ChatMessage {
80
        m := &ChatMessage{
81
                Timestamp: time.Now().Unix(),
82
83
                Player:  botSummary,
84
                Room:    room,
85
                Message: message,
86
87
                Bot: true,
88
        }
89
90
        m.Save()
91
        return m
92
}
func Lobby.GetPlayerSlotObj
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

296
func (lobby *Lobby) GetPlayerSlotObj(player *Player) (*LobbySlot, error) {
297
        slotObj := &LobbySlot{}
298
299
        err := db.DB.Where("player_id = ? AND lobby_id = ?", player.ID, lobby.ID).First(slotObj).Error
300
301
        return slotObj, err
302
}
func GetPlayerMessages
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/chat.go:

109
func GetPlayerMessages(player *Player) ([]*ChatMessage, error) {
110
        var messages []*ChatMessage
111
112
        err := db.DB.Table("chat_messages").Where("player_id = ?", player.ID).Order("room, created_at").Find(&messages).Error
113
114
        return messages, err
115
116
}
func Lobby.GetSlotRequirement
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

166
func (lobby *Lobby) GetSlotRequirement(slot int) (*Requirement, error) {
167
        req := &Requirement{}
168
        err := db.DB.Table("requirements").Where("lobby_id = ? AND slot = ?", lobby.ID, slot).First(req).Error
169
170
        return req, err
171
}
func Lobby.CurrentState
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

285
func (l *Lobby) CurrentState() LobbyState {
286
        var state int
287
        db.DB.DB().QueryRow("SELECT state FROM lobbies WHERE id = $1", l.ID).Scan(&state)
288
        return LobbyState(state)
289
}
func DecoratePlayerSummary
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player_decorators.go:

70
func DecoratePlayerSummary(p *Player) PlayerSummary {
71
        db.DB.Preload("Stats").First(p, p.ID)
72
        summary := PlayerSummary{
73
                Avatar:        p.Avatar,
74
                GameHours:     p.GameHours,
75
                ProfileURL:    p.Profileurl,
76
                LobbiesPlayed: p.Stats.TotalLobbies(),
77
                SteamID:       p.SteamID,
78
                Name:          p.Alias(),
79
                Tags:          decoratePlayerTags(p),
80
                Role:          helpers.RoleNames[p.Role],
81
        }
82
83
        return summary
84
}
func Lobby.GetPlayerIDBySlot
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

312
func (lobby *Lobby) GetPlayerIDBySlot(slot int) (uint, error) {
313
        slotObj := &LobbySlot{}
314
315
        err := db.DB.Where("lobby_id = ? AND slot = ?", lobby.ID, slot).First(slotObj).Error
316
317
        return uint(slotObj.PlayerID), err
318
}
func Lobby.FillSubstitute
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

377
func (lobby *Lobby) FillSubstitute(slot int) error {
378
        err := db.DB.Table("lobby_slots").Where("lobby_id = ? AND slot = ?", lobby.ID, slot).UpdateColumn("needs_sub", false).Error
379
        BroadcastSubList()
380
        return err
381
}
func Lobby.UnreadyAllPlayers
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

592
func (lobby *Lobby) UnreadyAllPlayers() error {
593
        err := db.DB.Table("lobby_slots").Where("lobby_id = ?", lobby.ID).UpdateColumn("ready", false).Error
594
595
        lobby.OnChange(false)
596
        return err
597
}
func Lobby.setInGameStatus
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

724
func (lobby *Lobby) setInGameStatus(player *Player, inGame bool) error {
725
        err := db.DB.Table("lobby_slots").Where("player_id = ? AND lobby_id = ?", player.ID, lobby.ID).UpdateColumn("in_game", inGame).Error
726
727
        lobby.OnChange(false)
728
        return err
729
}
func Lobby.IsEveryoneReady
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

606
func (lobby *Lobby) IsEveryoneReady() bool {
607
        readyPlayers := 0
608
        db.DB.Table("lobby_slots").Where("lobby_id = ? AND ready = ?", lobby.ID, true).Count(&readyPlayers)
609
610
        return readyPlayers == 2*NumberOfClassesMap[lobby.Type]
611
}
func Lobby.IsPlayerReady
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

585
func (lobby *Lobby) IsPlayerReady(player *Player) (bool, error) {
586
        var ready bool
587
        err := db.DB.DB().QueryRow("SELECT ready FROM lobby_slots WHERE lobby_id = $1 AND player_id = $2", lobby.ID, player.ID).Scan(&ready)
588
        return ready, err
589
}
func Lobby.Start
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

757
func (lobby *Lobby) Start() {
758
        db.DB.Table("lobbies").Where("id = ?", lobby.ID).Update("state", LobbyStateInProgress)
759
        time.AfterFunc(time.Minute*5, func() {
760
                if lobby.CurrentState() != LobbyStateEnded {
761
                        lobby.SubNotInGamePlayers()
762
                }
763
        })
764
}
func Player.BanUntil
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

379
func (player *Player) BanUntil(tim time.Time, t PlayerBanType, reason string) error {
380
        ban := PlayerBan{
381
                PlayerID: player.ID,
382
                Type:     t,
383
                Until:    tim,
384
                Reason:   reason,
385
        }
386
387
        return db.DB.Create(&ban).Error
388
}
func PlayerStats.IncreaseSubCount
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/playerStats.go:

58
func (ps *PlayerStats) IncreaseSubCount() {
59
        ps.Substitutes++
60
        database.DB.Save(ps)
61
}
func decoratePlayerTags
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player_decorators.go:

39
func decoratePlayerTags(p *Player) []string {
40
        tags := []string{helpers.RoleNames[p.Role]}
41
        return tags
42
}
func LogCustomAdminAction
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/admin_log.go:

21
func LogCustomAdminAction(playerid uint, reltext string, relid uint) error {
22
        entry := AdminLogEntry{
23
                PlayerID: playerid,
24
                RelID:    relid,
25
                RelText:  reltext,
26
        }
27
28
        return database.DB.Create(&entry).Error
29
}
func Lobby.SlotNeedsSubstitute
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

370
func (lobby *Lobby) SlotNeedsSubstitute(slot int) (needsSub bool) {
371
        //use database/sql API, since it's simpler here
372
        db.DB.DB().QueryRow("SELECT needs_sub FROM lobby_slots WHERE lobby_id = $1 AND slot = $2", lobby.ID, slot).Scan(&needsSub)
373
        return
374
}
func Player.IsBanned
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

374
func (player *Player) IsBanned(t PlayerBanType) bool {
375
        res, _ := player.IsBannedWithTime(t)
376
        return res
377
}
func BroadcastLobby
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

783
func BroadcastLobby(lobby *Lobby) {
784
        //db.DB.Preload("Spectators").First(&lobby, lobby.ID)
785
        room := strconv.FormatUint(uint64(lobby.ID), 10)
786
787
        broadcaster.SendMessageToRoom(fmt.Sprintf("%s_public", room), "lobbyData", DecorateLobbyData(lobby, true))
788
}
func FumbleLobbyPlayerJoined
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/fumble.go:

40
func FumbleLobbyPlayerJoined(lob *Lobby, player *Player, slot int) {
41
        team, class, _ := LobbyGetSlotInfoString(lob.Type, slot)
42
        fumbleAllowPlayer(lob.ID, strings.ToUpper(team)+"_"+strings.ToUpper(class), "")
43
}
func SendNotification
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/chat.go:

94
func SendNotification(message string, room int) {
95
        pub := fmt.Sprintf("%d_public", room)
96
        broadcaster.SendMessageToRoom(pub, "chatReceive", NewBotMessage(message, room))
97
}
func NewLobby
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

249
func NewLobby(mapName string, lobbyType LobbyType, league string, serverInfo ServerRecord, whitelist string, mumble bool, whitelistGroup, password string) *Lobby {
250
        lobby := &Lobby{
251
                Mode:            getGamemode(mapName, lobbyType),
252
                Type:            lobbyType,
253
                State:           LobbyStateInitializing,
254
                League:          league,
255
                MapName:         mapName,
256
                Whitelist:       whitelist, // that's a strange line
257
                Mumble:          mumble,
258
                ServerInfo:      serverInfo,
259
                PlayerWhitelist: whitelistGroup,
260
                SlotPassword:    password,
261
        }
262
263
        // Must specify CreatedBy manually if the lobby is created by a player
264
265
        return lobby
266
}
func BroadcastSubList
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

818
func BroadcastSubList() {
819
        subList := DecorateSubstituteList()
820
        broadcaster.SendMessageToRoom("0_public", "subListData", subList)
821
}
func GetWaitingLobbies
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

277
func GetWaitingLobbies() (lobbies []*Lobby) {
278
        db.DB.Where("state = ?", LobbyStateWaiting).Order("id desc").Find(&lobbies)
279
        return
280
}
func Lobby.BanPlayer
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

515
func (lobby *Lobby) BanPlayer(player *Player) {
516
        DisallowPlayer(lobby.ID, player.SteamID)
517
        db.DB.Model(lobby).Association("BannedPlayers").Append(player)
518
}
func NewPlayerStats
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/playerStats.go:

32
func NewPlayerStats() PlayerStats {
33
        stats := PlayerStats{}
34
35
        return stats
36
}
func NewChatMessage
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/chat.go:

43
func NewChatMessage(message string, room int, player *Player) *ChatMessage {
44
        record := &ChatMessage{
45
                Timestamp: time.Now().Unix(),
46
47
                PlayerID: player.ID,
48
                Player:   DecoratePlayerSummary(player),
49
50
                Room:    room,
51
                Message: message,
52
        }
53
54
        return record
55
}
func Lobby.GetPlayerSlot
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

305
func (lobby *Lobby) GetPlayerSlot(player *Player) (int, error) {
306
        slotObj, err := lobby.GetPlayerSlotObj(player)
307
308
        return slotObj.Slot, err
309
}
func Lobby.HasRequirements
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

181
func (lobby *Lobby) HasRequirements(slot int) bool {
182
        return lobby.HasSlotRequirement(slot)
183
}
func ChatMessage.Save
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/chat.go:

70
func (m *ChatMessage) Save() { db.DB.Save(m) }
func Requirement.Save
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

163
func (r *Requirement) Save() { db.DB.Save(r) }
func PlayerStats.TotalLobbies
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/playerStats.go:

38
func (ps *PlayerStats) TotalLobbies() int {
39
        return ps.PlayedSixesCount + ps.PlayedHighlanderCount + ps.PlayedFoursCount + ps.PlayedUltiduoCount + ps.PlayedBballCount
40
}
func Lobby.SetInGame
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

732
func (lobby *Lobby) SetInGame(player *Player) error {
733
        return lobby.setInGameStatus(player, true)
734
}
func Player.Unban
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

390
func (player *Player) Unban(t PlayerBanType) error {
391
        return db.DB.Model(&PlayerBan{}).Where("player_id = ? AND type = ? AND active = TRUE", player.ID, t).
392
                Update("active", "FALSE").Error
393
}
func Lobby.SetNotInGame
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

737
func (lobby *Lobby) SetNotInGame(player *Player) error {
738
        return lobby.setInGameStatus(player, false)
739
}
func Lobby.RealAfterSave
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

767
func (lobby *Lobby) RealAfterSave() {
768
        lobby.OnChange(true)
769
}
func BroadcastLobbyList
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

797
func BroadcastLobbyList() {
798
        broadcaster.SendMessageToRoom(
799
                fmt.Sprintf("%s_public", config.GlobalChatRoom),
800
                "lobbyListData", DecorateLobbyListData(GetWaitingLobbies()))
801
}
func End
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/pauling.go:

59
func End(lobbyId uint) {
60
        pauling.Call("Pauling.End", &Args{Id: lobbyId}, &Args{})
61
}
func LogAdminAction
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/admin_log.go:

31
func LogAdminAction(playerid uint, permission authority.AuthAction, relid uint) error {
32
        return LogCustomAdminAction(playerid, helpers.ActionNames[permission], relid)
33
}
func DecorateLobbyLeave
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby_decorators.go:

243
func DecorateLobbyLeave(lobby *Lobby) LobbyEvent {
244
        return LobbyEvent{lobby.ID}
245
}
func DecorateLobbyClosed
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby_decorators.go:

247
func DecorateLobbyClosed(lobby *Lobby) LobbyEvent {
248
        return LobbyEvent{lobby.ID}
249
}
func DisallowPlayer
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/pauling.go:

27
func DisallowPlayer(lobbyId uint, steamId string) error {
28
        return pauling.Call("Pauling.DisallowPlayer", &Args{Id: lobbyId, SteamId: steamId}, &Args{})
29
}
func DecorateLobbyData
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby_decorators.go:

133
func DecorateLobbyData(lobby *Lobby, includeDetails bool) LobbyData {
134
        lobbyData := LobbyData{
135
                ID:            lobby.ID,
136
                Mode:          lobby.Mode,
137
                Type:          formatMap[lobby.Type],
138
                Players:       lobby.GetPlayerNumber(),
139
                Map:           lobby.MapName,
140
                League:        lobby.League,
141
                Mumble:        lobby.Mumble,
142
                TwitchChannel: lobby.TwitchChannel,
143
144
                SteamGroup: lobby.PlayerWhitelist,
145
                Password:   lobby.SlotPassword != "",
146
        }
147
148
        lobbyData.Region.Name = lobby.RegionName
149
        lobbyData.Region.Code = lobby.RegionCode
150
151
        var classList = typeClassList[lobby.Type]
152
153
        classes := make([]ClassDetails, len(classList))
154
        lobbyData.MaxPlayers = NumberOfClassesMap[lobby.Type] * 2
155
156
        for slot, className := range classList {
157
                class := ClassDetails{
158
                        Red:   decorateSlotDetails(lobby, slot, includeDetails),
159
                        Blu:   decorateSlotDetails(lobby, slot+NumberOfClassesMap[lobby.Type], includeDetails),
160
                        Class: className,
161
                }
162
163
                classes[slot] = class
164
        }
165
166
        lobbyData.Classes = classes
167
        lobbyData.WhitelistID = lobby.Whitelist
168
169
        if !includeDetails {
170
                return lobbyData
171
        }
172
173
        var leader Player
174
        db.DB.Where("steam_id = ?", lobby.CreatedBySteamID).First(&leader)
175
176
        lobbyData.Leader = DecoratePlayerSummary(&leader)
177
        lobbyData.CreatedAt = lobby.CreatedAt.Unix()
178
        lobbyData.State = int(lobby.State)
179
180
        var specIDs []uint
181
        db.DB.Table("spectators_players_lobbies").Where("lobby_id = ?", lobby.ID).Pluck("player_id", &specIDs)
182
183
        spectators := make([]SpecDetails, len(specIDs))
184
185
        for i, spectatorID := range specIDs {
186
                specPlayer := &Player{}
187
                db.DB.First(specPlayer, spectatorID)
188
189
                specJs := SpecDetails{
190
                        Name:    specPlayer.Alias(),
191
                        SteamID: specPlayer.SteamID,
192
                }
193
194
                spectators[i] = specJs
195
        }
196
197
        lobbyData.Spectators = spectators
198
199
        return lobbyData
200
}
func decorateSlotDetails
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby_decorators.go:

107
func decorateSlotDetails(lobby *Lobby, slot int, includeDetails bool) SlotDetails {
108
        playerId, err := lobby.GetPlayerIDBySlot(slot)
109
        j := SlotDetails{Slot: slot, Filled: err == nil}
110
111
        if err == nil && includeDetails {
112
                var player Player
113
                db.DB.First(&player, playerId)
114
                db.DB.Preload("Stats").First(&player, player.ID)
115
116
                summary := DecoratePlayerSummary(&player)
117
                j.Player = &summary
118
119
                ready, _ := lobby.IsPlayerReady(&player)
120
                j.Ready = &ready
121
122
                ingame, _ := lobby.IsPlayerInGame(&player)
123
                j.InGame = &ingame
124
        }
125
126
        if lobby.HasSlotRequirement(slot) {
127
                j.Requirements, _ = lobby.GetSlotRequirement(slot)
128
        }
129
130
        return j
131
}
func Lobby.RemoveUnreadyPlayers
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

549
func (lobby *Lobby) RemoveUnreadyPlayers(spec bool) error {
550
        playerids := []uint{}
551
552
        if spec {
553
                //get list of player ids which are not ready
554
                err := db.DB.Table("lobby_slots").Where("lobby_id = ? AND ready = ?", lobby.ID, false).Pluck("player_id", &playerids).Error
555
                if err != nil {
556
                        return err
557
                }
558
        }
559
560
        //remove players which aren't ready
561
        err := db.DB.Where("lobby_id = ? AND ready = ?", lobby.ID, false).Delete(&LobbySlot{}).Error
562
        if spec {
563
                for _, id := range playerids {
564
                        player := &Player{}
565
                        db.DB.First(player, id)
566
                        lobby.AddSpectator(player)
567
                }
568
        }
569
        lobby.OnChange(true)
570
        return err
571
}
func LoadLobbySettings
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobbySettings.go:

145
func LoadLobbySettings(data []byte) error {
146
        var args struct {
147
                Formats []struct {
148
                        Name       string `json:"name"`
149
                        PrettyName string `json:"prettyName"`
150
                        Important  bool   `json:"important"`
151
                } `json:"formats"`
152
                Maps []struct {
153
                        Name    string         `json:"name"`
154
                        Formats map[string]int `json:"formats"`
155
                } `json:"maps"`
156
                Leagues []struct {
157
                        Name         string            `json:"name"`
158
                        PrettyName   string            `json:"prettyName"`
159
                        Descriptions map[string]string `json:"descriptions"`
160
                        Formats      map[string]bool   `json:"formats"`
161
                } `json:"leagues"`
162
                Whitelists []struct {
163
                        ID         int    `json:"id"`
164
                        PrettyName string `json:"prettyName"`
165
                        League     string `json:"league"`
166
                        Format     string `json:"format"`
167
                } `json:"whitelists"`
168
        }
169
170
        err := json.Unmarshal(data, &args)
171
        if err != nil {
172
                panic(err)
173
                return err
174
        }
175
176
        // formats
177
        LobbyFormats = make([]LobbyFormat, len(args.Formats))
178
        lobbyFormatFromName = make(map[string]int)
179
        for i, format := range args.Formats {
180
                LobbyFormats[i] = LobbyFormat{
181
                        Name:       format.Name,
182
                        PrettyName: format.PrettyName,
183
                        Important:  format.Important,
184
                }
185
                lobbyFormatFromName[format.Name] = i
186
        }
187
188
        // maps
189
        LobbyMaps = make([]LobbyMap, len(args.Maps))
190
        lobbyMapFromName = make(map[string]int)
191
        for i, amap := range args.Maps {
192
                lobbyMap := LobbyMap{
193
                        Name:    amap.Name,
194
                        Formats: make([]*LobbyMapFormat, 0, len(amap.Formats)),
195
                }
196
                for name, importance := range amap.Formats {
197
                        if lobbyFormat, ok := GetLobbyFormat(name); ok {
198
                                lobbyMap.Formats = append(lobbyMap.Formats, &LobbyMapFormat{
199
                                        Format:     lobbyFormat,
200
                                        Importance: importance,
201
                                })
202
                        } else {
203
                                return errors.New(fmt.Sprintf("Referenced a non existing format %q", name))
204
                        }
205
                }
206
207
                LobbyMaps[i] = lobbyMap
208
                lobbyMapFromName[amap.Name] = i
209
        }
210
211
        // leagues
212
        LobbyLeagues = make([]LobbyLeague, len(args.Leagues))
213
        lobbyLeagueFromName = make(map[string]int)
214
        for i, league := range args.Leagues {
215
                lobbyLeague := LobbyLeague{
216
                        Name:         league.Name,
217
                        PrettyName:   league.PrettyName,
218
                        Descriptions: make([]*LobbyLeagueDescription, 0, len(league.Descriptions)),
219
                        Formats:      make([]*LobbyLeagueFormat, 0, len(league.Formats)),
220
                }
221
                for atype, description := range league.Descriptions {
222
                        lobbyLeagueDescription := &LobbyLeagueDescription{
223
                                MapType:     MapType(atype),
224
                                Description: description,
225
                        }
226
                        lobbyLeague.Descriptions = append(lobbyLeague.Descriptions, lobbyLeagueDescription)
227
                }
228
                for name, used := range league.Formats {
229
                        if lobbyFormat, ok := GetLobbyFormat(name); ok {
230
                                lobbyLeagueFormat := &LobbyLeagueFormat{
231
                                        Format: lobbyFormat,
232
                                        Used:   used,
233
                                }
234
                                lobbyLeague.Formats = append(lobbyLeague.Formats, lobbyLeagueFormat)
235
                        } else {
236
                                return errors.New(fmt.Sprintf("Referenced a non existing format %q", name))
237
                        }
238
                }
239
240
                LobbyLeagues[i] = lobbyLeague
241
                lobbyLeagueFromName[league.Name] = i
242
        }
243
244
        // whitelists
245
        LobbyWhitelists = make([]LobbyWhitelist, len(args.Whitelists))
246
        lobbyWhitelistFromID = make(map[int]int)
247
        for i, whitelist := range args.Whitelists {
248
                if lobbyLeague, ok := GetLobbyLeague(whitelist.League); ok {
249
                        if lobbyFormat, ok := GetLobbyFormat(whitelist.Format); ok {
250
                                lobbyWhitelist := LobbyWhitelist{
251
                                        ID:         whitelist.ID,
252
                                        PrettyName: whitelist.PrettyName,
253
                                        League:     lobbyLeague,
254
                                        Format:     lobbyFormat,
255
                                }
256
257
                                LobbyWhitelists[i] = lobbyWhitelist
258
                                lobbyWhitelistFromID[whitelist.ID] = i
259
                        } else {
260
                                return errors.New(fmt.Sprintf("Referenced a non existing format %q", whitelist.Format))
261
                        }
262
                } else {
263
                        return errors.New(fmt.Sprintf("Referenced a non existing league %q", whitelist.League))
264
                }
265
        }
266
267
        return nil
268
}
func fumbleAllowPlayer
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/fumble.go:

21
func fumbleAllowPlayer(lobbyId uint, playerName string, playerTeam string) error {
22
        user := mumble.User{}
23
        user.Name = playerName
24
        user.Team = mumble.Team(playerTeam)
25
26
        err := fumble.Call("Fumble.AllowPlayer", &mumble.LobbyArgs{
27
                User: user, LobbyID: lobbyId}, &struct{}{})
28
        if err != nil {
29
                logrus.Error(err)
30
        }
31
32
        return nil
33
}
func Player.GetSetting
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

349
func (player *Player) GetSetting(key string) string {
350
        db.DB.First(player)
351
        if player.Settings == nil {
352
                return ""
353
        }
354
355
        value, ok := player.Settings[key]
356
        if !ok {
357
                return ""
358
        }
359
360
        return *value
361
}
func Lobby.UpdateStats
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

706
func (lobby *Lobby) UpdateStats() {
707
        db.DB.Preload("Slots").First(lobby, lobby.ID)
708
709
        for _, slot := range lobby.Slots {
710
                player := &Player{}
711
                err := db.DB.First(player, slot.PlayerID).Error
712
                if err != nil {
713
                        logrus.Error(err)
714
                        return
715
                }
716
                db.DB.Preload("Stats").First(player, slot.PlayerID)
717
                player.Stats.PlayedCountIncrease(lobby.Type)
718
                player.Stats.IncreaseClassCount(lobby, slot.Slot)
719
                player.Save()
720
        }
721
        lobby.OnChange(false)
722
}
func LobbyGetSlotInfo
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/classMaps.go:

125
func LobbyGetSlotInfo(lobbytype LobbyType, slot int) (int, int, *helpers.TPError) {
126
        classList := typeClassList[lobbytype]
127
128
        if slot < len(classList) {
129
                return 0, slot, nil
130
        } else if slot < 2*len(classList) {
131
                return 1, slot - len(classList), nil
132
        } else {
133
                return 0, 0, helpers.NewTPError("Invalid slot", -1)
134
        }
135
}
func Lobby.RemoveSpectator
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

625
func (lobby *Lobby) RemoveSpectator(player *Player, broadcast bool) *helpers.TPError {
626
        err := db.DB.Model(lobby).Association("Spectators").Delete(player).Error
627
        if err != nil {
628
                return helpers.NewTPError(err.Error(), -1)
629
        }
630
        if broadcast {
631
                lobby.OnChange(false)
632
        }
633
        return nil
634
}
func Lobby.RemovePlayer
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

503
func (lobby *Lobby) RemovePlayer(player *Player) *helpers.TPError {
504
        err := db.DB.Where("player_id = ? AND lobby_id = ?", player.ID, lobby.ID).Delete(&LobbySlot{}).Error
505
        if err != nil {
506
                return helpers.NewTPError(err.Error(), -1)
507
        }
508
509
        DisallowPlayer(lobby.ID, player.SteamID)
510
        lobby.OnChange(true)
511
        return nil
512
}
func GetLobbyByID
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

348
func GetLobbyByID(id uint) (*Lobby, *helpers.TPError) {
349
        nonExistentLobby := helpers.NewTPError("Lobby not in the database", -1)
350
351
        lob := &Lobby{}
352
        err := db.DB.First(lob, id).Error
353
354
        if err != nil {
355
                return nil, nonExistentLobby
356
        }
357
358
        return lob, nil
359
}
func GetLobbyByIDServer
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

334
func GetLobbyByIDServer(id uint) (*Lobby, *helpers.TPError) {
335
        nonExistentLobby := helpers.NewTPError("Lobby not in the database", -1)
336
337
        lob := &Lobby{}
338
        err := db.DB.Preload("ServerInfo").First(lob, id).Error
339
340
        if err != nil {
341
                return nil, nonExistentLobby
342
        }
343
344
        return lob, nil
345
}
func LobbyMap.GetFormat
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobbySettings.go:

37
func (m *LobbyMap) GetFormat(formatName string) (*LobbyMapFormat, bool) {
38
        for _, mapFormat := range m.Formats {
39
                if mapFormat.Format.Name == formatName {
40
                        return mapFormat, true
41
                }
42
        }
43
        if format, ok := GetLobbyFormat(formatName); ok {
44
                return &LobbyMapFormat{
45
                        Format:     format,
46
                        Importance: 0,
47
                }, true
48
        }
49
        return nil, false
50
}
func NewPlayer
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

79
func NewPlayer(steamId string) (*Player, error) {
80
        player := &Player{SteamID: steamId}
81
82
        if config.Constants.SteamDevAPIKey == "" {
83
                player.Stats = NewPlayerStats()
84
85
                err := player.UpdatePlayerInfo()
86
                if err != nil {
87
                        return &Player{}, err
88
                }
89
        } else {
90
                player.Stats = PlayerStats{}
91
        }
92
93
        player.MumbleUsername = player.GenMumbleUsername()
94
        player.MumbleAuthkey = player.GenAuthKey()
95
96
        return player, nil
97
}
func Lobby.UnreadyPlayer
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

531
func (lobby *Lobby) UnreadyPlayer(player *Player) *helpers.TPError {
532
        err := db.DB.Table("lobby_slots").Where("lobby_id = ? AND player_id = ?", lobby.ID, player.ID).UpdateColumn("ready", false).Error
533
        if err != nil {
534
                return helpers.NewTPError("Player is not in the lobby.", 5)
535
        }
536
537
        lobby.OnChange(false)
538
        return nil
539
}
func Lobby.IsPlayerInGame
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

574
func (lobby *Lobby) IsPlayerInGame(player *Player) (bool, error) {
575
        var ingame bool
576
        err := db.DB.DB().QueryRow("SELECT in_game FROM lobby_slots WHERE lobby_id = $1 AND player_id = $2", lobby.ID, player.ID).Scan(&ingame)
577
        if err != nil {
578
                return false, err
579
        }
580
581
        return ingame, err
582
}
func Player.GetSpectatingIds
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

288
func (player *Player) GetSpectatingIds() ([]uint, *helpers.TPError) {
289
        var ids []uint
290
        err := db.DB.Model(&Lobby{}).
291
                Joins("INNER JOIN spectators_players_lobbies l ON l.lobby_id = lobbies.id").
292
                Where("l.player_id = ? AND lobbies.state <> ?", player.ID, LobbyStateEnded).
293
                Pluck("id", &ids).Error
294
295
        if err != nil {
296
                return nil, helpers.NewTPError(err.Error(), 1)
297
        }
298
299
        return ids, nil
300
}
func Player.IsSpectatingID
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

278
func (player *Player) IsSpectatingID(lobbyid uint) bool {
279
        count := 0
280
        err := db.DB.Table("spectators_players_lobbies").Where("player_id = ? AND lobby_id = ?", player.ID, lobbyid).Count(&count).Error
281
        if err != nil {
282
                return false
283
        }
284
        return count != 0
285
}
func Player.GetActiveBans
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

395
func (player *Player) GetActiveBans() ([]*PlayerBan, error) {
396
        var bans []*PlayerBan
397
        err := db.DB.Where("player_id = ? AND active = TRUE AND until > now()", player.ID).Find(&bans).Error
398
        if err != nil {
399
                return nil, err
400
        }
401
        return bans, nil
402
}
func Lobby.AddSpectator
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

614
func (lobby *Lobby) AddSpectator(player *Player) *helpers.TPError {
615
        err := db.DB.Model(lobby).Association("Spectators").Append(player).Error
616
        if err != nil {
617
                return helpers.NewTPError(err.Error(), -1)
618
        }
619
        lobby.OnChange(false)
620
        return nil
621
}
func Lobby.GetPlayerNumber
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

637
func (lobby *Lobby) GetPlayerNumber() int {
638
        count := 0
639
        err := db.DB.Table("lobby_slots").Where("lobby_id = ?", lobby.ID).Count(&count).Error
640
        if err != nil {
641
                return 0
642
        }
643
        return count
644
}
func GetPlayerWithStats
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

247
func GetPlayerWithStats(steamid string) (*Player, *helpers.TPError) {
248
        var player = Player{}
249
        err := db.DB.Where("steam_id = ?", steamid).Preload("Stats").First(&player).Error
250
        if err != nil {
251
                return nil, helpers.NewTPError("Player is not in the database", -1)
252
        }
253
        return &player, nil
254
}
func GetPlayerBySteamID
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

237
func GetPlayerBySteamID(steamid string) (*Player, *helpers.TPError) {
238
        var player = Player{}
239
        err := db.DB.Where("steam_id = ?", steamid).First(&player).Error
240
        if err != nil {
241
                return nil, helpers.NewTPError("Player is not in the database", -1)
242
        }
243
        return &player, nil
244
}
func Lobby.ReadyPlayer
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

521
func (lobby *Lobby) ReadyPlayer(player *Player) *helpers.TPError {
522
        err := db.DB.Table("lobby_slots").Where("lobby_id = ? AND player_id = ?", lobby.ID, player.ID).UpdateColumn("ready", true).Error
523
        if err != nil {
524
                return helpers.NewTPError("Player is not in the lobby.", 5)
525
        }
526
        lobby.OnChange(false)
527
        return nil
528
}
func GetPlayerByID
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

226
func GetPlayerByID(ID uint) (*Player, error) {
227
        player := &Player{}
228
229
        if err := db.DB.First(player, ID).Error; err != nil {
230
                return nil, err
231
        }
232
233
        return player, nil
234
}
func Player.Alias
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

205
func (p *Player) Alias() string {
206
        alias := p.GetSetting("siteAlias")
207
        if alias == "" {
208
                return p.Name
209
        }
210
211
        return alias
212
}
func FumbleLobbyEnded
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/fumble.go:

45
func FumbleLobbyEnded(lob *Lobby) {
46
        err := fumble.Call("Fumble.EndLobby", lob.ID, nil)
47
        if err != nil {
48
                logrus.Error(err)
49
        }
50
}
func GetLobbyFormat
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobbySettings.go:

95
func GetLobbyFormat(formatName string) (*LobbyFormat, bool) {
96
        if format, ok := lobbyFormatFromName[formatName]; ok {
97
                return &LobbyFormats[format], true
98
        }
99
        return nil, false
100
}
func GetLobbyMap
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobbySettings.go:

102
func GetLobbyMap(mapName string) (*LobbyMap, bool) {
103
        if amap, ok := lobbyMapFromName[mapName]; ok {
104
                return &LobbyMaps[amap], true
105
        }
106
        return nil, false
107
}
func GetLobbyLeague
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobbySettings.go:

109
func GetLobbyLeague(leagueName string) (*LobbyLeague, bool) {
110
        if league, ok := lobbyLeagueFromName[leagueName]; ok {
111
                return &LobbyLeagues[league], true
112
        }
113
        return nil, false
114
}
func Lobby.AddPlayer
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

385
func (lobby *Lobby) AddPlayer(player *Player, slot int, password string) *helpers.TPError {
386
        /* Possible errors while joining
387
         * Slot has been filled
388
         * Player has already joined a lobby
389
         * anything else?
390
         */
391
392
        //check if slot password is valid
393
        if lobby.SlotPassword != "" && lobby.SlotPassword != password {
394
                return InvalidPasswordErr
395
        }
396
397
        num := 0
398
399
        //Check if player is banned
400
        //TODO(nonagon): It should really be possible to do this query using relations
401
        if err := db.DB.Table("banned_players_lobbies").
402
                Where("lobby_id = ? AND player_id = ?", lobby.ID, player.ID).
403
                Count(&num).Error; num > 0 || err != nil {
404
                //logrus.Debug(fmt.Sprint(err))
405
                return LobbyBanErr
406
        }
407
408
        if slot >= 2*NumberOfClassesMap[lobby.Type] || slot < 0 {
409
                return BadSlotErr
410
        }
411
412
        var slotChange bool
413
        //Check if the player is currently in another lobby
414
        if currLobbyID, err := player.GetLobbyID(false); err == nil {
415
                if currLobbyID != lobby.ID {
416
                        //if the player is in a different lobby, remove them from that lobby
417
                        //plus substitute them
418
                        curLobby, _ := GetLobbyByID(currLobbyID)
419
420
                        if curLobby.State == LobbyStateInProgress {
421
                                curLobby.Substitute(player)
422
                        } else {
423
                                curLobby.RemovePlayer(player)
424
                                curLobby.AddSpectator(player)
425
                        }
426
427
                } else { //player is in the same lobby, they're changing their slots
428
                        //assign the player to a new slot
429
                        if lobby.SlotNeedsSubstitute(slot) {
430
                                //the slot needs a substitute (which happens when the lobby is in progress),
431
                                //so players already in the lobby cannot fill it.
432
                                return NeedsSubErr
433
                        }
434
                        db.DB.Where("player_id = ? AND lobby_id = ?", player.ID, lobby.ID).Delete(&LobbySlot{})
435
                        slotChange = true
436
                }
437
        }
438
439
        if !slotChange {
440
                //check if the player is in the steam group whitelist
441
                url := fmt.Sprintf(`http://steamcommunity.com/groups/%s/memberslistxml/?xml=1`,
442
                        lobby.PlayerWhitelist)
443
444
                if lobby.PlayerWhitelist != "" && !helpers.IsWhitelisted(player.SteamID, url) {
445
                        return NotWhitelistedErr
446
                }
447
448
                if lobby.HasRequirements(slot) {
449
                        //check if player fits the requirements for the slot
450
                        if ok, err := lobby.FitsRequirements(player, slot); !ok {
451
                                return err
452
                        }
453
                }
454
455
                //check if player has been subbed to the twitch channel (if any)
456
                if lobby.TwitchChannel != "" {
457
                        //check if player has connected their twitch account
458
                        if player.TwitchAccessToken == "" {
459
                                return helpers.NewTPError("You need to connect your Twitch Account first to join the lobby.", -1)
460
                        }
461
                        if !player.IsSubscribed(lobby.TwitchChannel) {
462
                                err := fmt.Sprintf("You aren't subscribed to %s", lobby.TwitchChannel)
463
                                return helpers.NewTPError(err, -1)
464
                        }
465
                }
466
        }
467
468
        // Check if player is a substitute (the slot needs a subtitute)
469
        if lobby.SlotNeedsSubstitute(slot) {
470
                //kicks previous slot occupant if they're in-game, resets their !rep count, removes them from the lobby
471
                DisallowPlayer(lobby.ID, player.SteamID)
472
                //delete previous slot
473
                db.DB.Where("lobby_id = ? AND slot = ?", lobby.ID, slot).Delete(&LobbySlot{})
474
                BroadcastSubList() //since the sub slot has been deleted, broadcast the updated substitute list
475
                //notify players in game server of subtitute
476
                class, team, _ := LobbyGetSlotInfoString(lobby.Type, slot)
477
                Say(lobby.ID, fmt.Sprintf("Substitute found for %s %s: %s (%s)", team, class, player.Name, player.SteamID))
478
                //allow player in mumble
479
                FumbleLobbyPlayerJoinedSub(lobby, player, slot)
480
        } else if _, err := lobby.GetPlayerIDBySlot(slot); err == nil {
481
                return FilledErr
482
        } else {
483
                FumbleLobbyPlayerJoined(lobby, player, slot) // no errors, al
484
        }
485
486
        //try to remove them from spectators
487
        lobby.RemoveSpectator(player, true)
488
489
        newSlotObj := &LobbySlot{
490
                PlayerID: player.ID,
491
                LobbyID:  lobby.ID,
492
                Slot:     slot,
493
        }
494
495
        db.DB.Create(newSlotObj)
496
497
        lobby.OnChange(true)
498
499
        return nil
500
}
func DecorateLobbyListData
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby_decorators.go:

210
func DecorateLobbyListData(lobbies []*Lobby) []LobbyData {
211
        var lobbyList = make([]LobbyData, len(lobbies))
212
213
        for i, lobby := range lobbies {
214
                lobbyData := DecorateLobbyData(lobby, false)
215
                lobbyList[i] = lobbyData
216
        }
217
218
        return lobbyList
219
}
func PlayerStats.PlayedCountIncrease
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/playerStats.go:

42
func (ps *PlayerStats) PlayedCountIncrease(lt LobbyType) {
43
        switch lt {
44
        case LobbyTypeSixes:
45
                ps.PlayedSixesCount++
46
        case LobbyTypeHighlander:
47
                ps.PlayedHighlanderCount++
48
        case LobbyTypeFours:
49
                ps.PlayedFoursCount++
50
        case LobbyTypeBball:
51
                ps.PlayedBballCount++
52
        case LobbyTypeUltiduo:
53
                ps.PlayedUltiduoCount++
54
        }
55
        database.DB.Save(ps)
56
}
func getGamemode
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

215
func getGamemode(mapName string, lobbyType LobbyType) string {
216
        switch {
217
        case strings.HasPrefix(mapName, "koth"):
218
                if lobbyType == LobbyTypeUltiduo {
219
                        return "ultiduo"
220
                }
221
222
                return "koth"
223
224
        case strings.HasPrefix(mapName, "ctf"):
225
                if lobbyType == LobbyTypeBball {
226
                        return "bball"
227
                }
228
229
                return "ctf"
230
231
        case strings.HasPrefix(mapName, "cp"):
232
                if mapName == "cp_gravelpit" {
233
                        return "a/d"
234
                }
235
236
                return "5cp"
237
238
        case strings.HasPrefix(mapName, "pl"):
239
                return "payload"
240
241
        case strings.HasPrefix(mapName, "arena"):
242
                return "arena"
243
        }
244
245
        return "unknown"
246
}
func Player.UpdatePlayerInfo
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

303
func (player *Player) UpdatePlayerInfo() error {
304
        if config.Constants.SteamDevAPIKey == "" {
305
                return nil
306
        }
307
308
        player.SetExternalLinks()
309
310
        scraper.SetSteamApiKey(config.Constants.SteamDevAPIKey)
311
        p, _ := GetPlayerBySteamID(player.SteamID)
312
313
        if p != nil {
314
                *player = *p
315
        }
316
317
        playerInfo, infoErr := scraper.GetPlayerInfo(player.SteamID)
318
        if infoErr != nil {
319
                return infoErr
320
        }
321
322
        // profile state is 1 when the player have a steam community profile
323
        if playerInfo.Profilestate == 1 && playerInfo.Visibility == "public" {
324
                pHours, hErr := scraper.GetTF2Hours(player.SteamID)
325
326
                if hErr != nil {
327
                        return errors.New("models.UpdatePlayerInfo: " + hErr.Error())
328
                }
329
330
                player.GameHours = pHours
331
        }
332
333
        player.Profileurl = playerInfo.Profileurl
334
        player.Avatar = playerInfo.Avatar
335
        player.Name = playerInfo.Name
336
337
        return nil
338
}
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

99
func (player *Player) SetExternalLinks() {
100
        player.ExternalLinks = make(gorm.Hstore)
101
        defer player.Save()
102
103
        // logs.tf
104
        logstf := fmt.Sprintf(`http://logs.tf/profile/%s`, player.SteamID)
105
        resp, err := helpers.HTTPClient.Get(logstf)
106
        if err == nil && resp.StatusCode == 200 {
107
                player.ExternalLinks["logstf"] = &logstf
108
        }
109
110
        // UGC
111
        ugc := fmt.Sprintf(`http://www.ugcleague.com/players_page.cfm?player_id=%s`, player.SteamID)
112
        resp, err = helpers.HTTPClient.Get(ugc)
113
        if err == nil && resp.StatusCode == 200 {
114
                player.ExternalLinks["ugc"] = &ugc
115
        }
116
117
        var reply struct {
118
                Player *struct {
119
                        ID      int    `json:"id"`
120
                        Country string `json:"country"`
121
                } `json:"player,omitempty"`
122
                Status struct {
123
                        Code int `json:"code"`
124
                }
125
        }
126
127
        etf2lURL := fmt.Sprintf(`http://api.etf2l.org/player/%s`, player.SteamID)
128
        req, _ := http.NewRequest("GET", etf2lURL, nil)
129
        req.Header.Set("Content-Type", "application/json")
130
        req.Header.Set("Accept", "application/json")
131
        resp, err = helpers.HTTPClient.Do(req)
132
        if err != nil {
133
                logrus.Error(err)
134
                return
135
        }
136
137
        dec := json.NewDecoder(resp.Body)
138
        err = dec.Decode(&reply)
139
        if err != nil {
140
                logrus.Error(err)
141
                return
142
        }
143
144
        if reply.Player != nil {
145
                url := fmt.Sprintf(`http://beta.etf2l.org/forum/user/%d/`, reply.Player.ID)
146
                player.ExternalLinks["etf2l"] = &url
147
        }
148
149
        // teamfortress.tv
150
        tftv := fmt.Sprintf("http://www.teamfortress.tv/api/users/%s", player.SteamID)
151
        resp, err = helpers.HTTPClient.Get(tftv)
152
        if err != nil {
153
                logrus.Error(err)
154
                return
155
        }
156
157
        var tftvReply struct {
158
                UserName string `json:"user_name"`
159
        }
160
161
        dec = json.NewDecoder(resp.Body)
162
        err = dec.Decode(&reply)
163
        if err != nil {
164
                logrus.Error(err)
165
                return
166
        }
167
168
        if tftvReply.UserName != "" {
169
                uname := fmt.Sprintf("http://teamfortress.tv/user/%s", tftvReply.UserName)
170
                player.ExternalLinks["tftv"] = &uname
171
        }
172
173
}
func DecoratePlayerProfileJson
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player_decorators.go:

44
func DecoratePlayerProfileJson(p *Player) PlayerProfile {
45
        db.DB.Preload("Stats").First(p, p.ID)
46
        profile := PlayerProfile{}
47
48
        p.Stats.Total = p.Stats.TotalLobbies()
49
        profile.Stats = p.Stats
50
51
        profile.CreatedAt = p.CreatedAt.Unix()
52
        profile.GameHours = p.GameHours
53
        profile.SteamID = p.SteamID
54
        profile.Avatar = p.Avatar
55
        profile.Name = p.Alias()
56
        profile.Role = helpers.RoleNames[p.Role]
57
        profile.TwitchName = p.TwitchName
58
        profile.ExternalLinks = p.ExternalLinks
59
60
        // TODO ban info
61
        var slots []*LobbySlot
62
        db.DB.Table("lobby_slots").Where("player_id = ?", p.ID).Order("id desc").Limit("5").Find(&slots)
63
        for _, slot := range slots {
64
                lobby, _ := GetLobbyByID(slot.LobbyID)
65
                profile.Lobbies = append(profile.Lobbies, DecorateLobbyData(lobby, false))
66
        }
67
        return profile
68
}
func ConnectRPC
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/rpc.go:

19
func ConnectRPC() {
20
        var err error
21
22
        if config.Constants.PaulingAddr != "" {
23
                pauling, err = rpcconn.DialHTTP("tcp", etcd.Address{Address: config.Constants.PaulingAddr})
24
                if err != nil {
25
                        logrus.Fatal(err)
26
                }
27
28
                pauling.Call("Pauling.Ping", struct{}{}, &struct{}{})
29
                logrus.Info("Connected to Pauling")
30
        }
31
32
        if config.Constants.FumbleAddr != "" {
33
                fumble, err = rpcconn.DialHTTP("tcp", etcd.Address{Address: config.Constants.FumbleAddr})
34
                if err != nil {
35
                        logrus.Fatal(err)
36
                }
37
                logrus.Info("Connected to Fumble")
38
        }
39
}
func DecorateLobbyConnect
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby_decorators.go:

221
func DecorateLobbyConnect(lobby *Lobby, name string, slot int) LobbyConnectData {
222
        l := LobbyConnectData{}
223
        l.ID = lobby.ID
224
        l.Time = lobby.CreatedAt.Unix()
225
        l.Pass = lobby.ServerInfo.ServerPassword
226
227
        l.Game.Host = lobby.ServerInfo.Host
228
229
        l.Mumble.Address = config.Constants.MumbleAddr
230
        l.Mumble.Password = config.Constants.MumblePassword
231
        l.Mumble.Channel = "match" + strconv.FormatUint(uint64(lobby.ID), 10)
232
        team, class, _ := LobbyGetSlotInfoString(lobby.Type, slot)
233
        nick := strings.ToUpper(team) + "_" + strings.ToUpper(class)
234
        l.Mumble.Nick = nick
235
236
        return l
237
}
func Player.IsSubscribed
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

414
func (p *Player) IsSubscribed(channel string) bool {
415
        url := fmt.Sprintf("https://api.twitch.tv/kraken/users/%s/subscriptions/%s", p.TwitchName, channel)
416
417
        req, _ := http.NewRequest("GET", url, nil)
418
        req.Header.Add("Accept", "application/vnd.twitchtv.v3+json")
419
        req.Header.Add("Authorization", "OAuth "+p.TwitchAccessToken)
420
421
        resp, err := client.Do(req)
422
        if err != nil {
423
                logrus.Error(err)
424
                return false
425
        }
426
427
        var reply struct {
428
                ID string `json:"_id"`
429
        }
430
431
        dec := json.NewDecoder(resp.Body)
432
        err = dec.Decode(&reply)
433
434
        //if status code is 404, the user isn't subscribed
435
        return err == nil && resp.StatusCode != 404
436
}
func GetScrollback
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/chat.go:

119
func GetScrollback(room int) ([]*ChatMessage, error) {
120
        var messages []*ChatMessage
121
122
        err := db.DB.Table("chat_messages").Where("room = ? AND deleted = FALSE", room).Order("id desc").Limit(20).Find(&messages).Error
123
124
        for _, message := range messages {
125
                var player Player
126
                if message.Bot {
127
                        message.Player = botSummary
128
                } else {
129
                        db.DB.First(&player, message.PlayerID)
130
                        message.Player = DecoratePlayerSummary(&player)
131
                }
132
                message.Timestamp = message.CreatedAt.Unix()
133
        }
134
        return messages, err
135
}
func InitializeLobbySettings
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobbySettings.go:

123
func InitializeLobbySettings(fileName string) {
124
        realPath, err := filepath.Abs(fileName)
125
        if err != nil {
126
                logrus.Fatal(err.Error())
127
                return
128
        }
129
130
        err = LoadLobbySettingsFromFile(realPath)
131
        if err != nil {
132
                logrus.Fatal(err.Error())
133
        }
134
}
func FumbleLobbyCreated
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/fumble.go:

10
func FumbleLobbyCreated(lob *Lobby) error {
11
        err := fumble.Call("Fumble.CreateLobby", lob.ID, &struct{}{})
12
13
        if err != nil {
14
                logrus.Error(err)
15
                return err
16
        }
17
18
        return nil
19
}
func Lobby.IsSlotFilled
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

652
func (lobby *Lobby) IsSlotFilled(slot int) bool {
653
        _, err := lobby.GetPlayerIDBySlot(slot)
654
        if err != nil {
655
                return false
656
        }
657
        return true
658
}
func LoadLobbySettingsFromFile
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobbySettings.go:

136
func LoadLobbySettingsFromFile(fileName string) error {
137
        data, err := ioutil.ReadFile(fileName)
138
        if err != nil {
139
                return err
140
        }
141
142
        return LoadLobbySettings(data)
143
}
func Lobby.SetupServer
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

667
func (lobby *Lobby) SetupServer() error {
668
        if lobby.State == LobbyStateEnded {
669
                return nil
670
        }
671
672
        err := SetupServer(lobby.ID, lobby.ServerInfo, lobby.Type, lobby.League, lobby.Whitelist, lobby.MapName)
673
        return err
674
}
func GetAllActiveBans
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/player.go:

404
func GetAllActiveBans() []*PlayerBan {
405
        var bans []*PlayerBan
406
        db.DB.Where("active = TRUE AND until > now()").Find(&bans)
407
        return bans
408
}
func GetLobbyWhitelist
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobbySettings.go:

116
func GetLobbyWhitelist(whitelistId int) (*LobbyWhitelist, bool) {
117
        if whitelist, ok := lobbyWhitelistFromID[whitelistId]; ok {
118
                return &LobbyWhitelists[whitelist], true
119
        }
120
        return nil, false
121
}
func ChatMessage.Send
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/chat.go:

72
func (m *ChatMessage) Send() {
73
        broadcaster.SendMessageToRoom(fmt.Sprintf("%d_public", m.Room), "chatReceive", m)
74
        if m.Room != 0 {
75
                broadcaster.SendMessageToRoom(fmt.Sprintf("%d_private", m.Room), "chatReceive", m)
76
        }
77
}
func IsPlayerInServer
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/pauling.go:

52
func IsPlayerInServer(steamid string) (reply bool) {
53
        args := &Args{SteamId: steamid}
54
        pauling.Call("Pauling.IsPlayerInServer", &args, &reply)
55
56
        return
57
}
func NewRequirement
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

152
func NewRequirement(lobbyID uint, slot int, hours int, lobbies int) *Requirement {
153
        r := &Requirement{
154
                LobbyID: lobbyID,
155
                Slot:    slot,
156
                Hours:   hours,
157
                Lobbies: lobbies}
158
        db.DB.Save(r)
159
160
        return r
161
}
func serverExists
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/pauling.go:

67
func serverExists(lobbyID uint) (exists bool) {
68
        pauling.Call("Pauling.Exists", lobbyID, &exists)
69
        return
70
}
func SetupServer
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/pauling.go:

31
func SetupServer(lobbyId uint, info ServerRecord, lobbyType LobbyType, league string,
32
        whitelist string, mapName string) error {
33
34
        args := &Args{
35
                Id:        lobbyId,
36
                Info:      info,
37
                Type:      lobbyType,
38
                League:    league,
39
                Whitelist: whitelist,
40
                Map:       mapName}
41
        return pauling.Call("Pauling.SetupServer", args, &Args{})
42
}
func Lobby.GetAllSlots
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

661
func (lobby *Lobby) GetAllSlots() []LobbySlot {
662
        db.DB.Preload("Slots").First(lobby, lobby.ID)
663
        return lobby.Slots
664
}
func Lobby.GetUnreadyPlayers
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

543
func (lobby *Lobby) GetUnreadyPlayers() (players []*Player) {
544
        db.DB.Table("players").Joins("INNER JOIN lobby_slots ON lobby_slots.player_id = players.id").Where("lobby_slots.lobby_id = ? AND lobby_slots.ready = ?", lobby.ID, false).Find(&players)
545
        return
546
}
func @759:32
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

759
func() {
760
                if lobby.CurrentState() != LobbyStateEnded {
761
                        lobby.SubNotInGamePlayers()
762
                }
763
        }
func FumbleLobbyPlayerJoinedSub
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/fumble.go:

35
func FumbleLobbyPlayerJoinedSub(lob *Lobby, player *Player, slot int) {
36
        team, class, _ := LobbyGetSlotInfoString(lob.Type, slot)
37
        fumbleAllowPlayer(lob.ID, strings.ToUpper(team)+"_"+strings.ToUpper(class), strings.ToUpper(team))
38
}
func Lobby.Delete
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

271
func (lobby *Lobby) Delete() {
272
        db.DB.Delete(lobby)
273
        db.DB.Delete(&lobby.ServerInfo)
274
}
func ReExecConfig
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/pauling.go:

44
func ReExecConfig(lobbyId uint) error {
45
        return pauling.Call("Pauling.ReExecConfig", &Args{Id: lobbyId}, &Args{})
46
}
func LobbyData.Send
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby_decorators.go:

202
func (l LobbyData) Send() {
203
        broadcaster.SendMessageToRoom(fmt.Sprintf("%d_public", l.ID), "lobbyData", l)
204
}
func VerifyInfo
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/pauling.go:

48
func VerifyInfo(info ServerRecord) error {
49
        return pauling.Call("Pauling.VerifyInfo", &info, &Args{})
50
}
func NewInGameChatMessage
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/chat.go:

57
func NewInGameChatMessage(lobby *Lobby, player *Player, message string) *ChatMessage {
58
        return &ChatMessage{
59
                Timestamp: time.Now().Unix(),
60
61
                PlayerID: player.ID,
62
                Player:   DecoratePlayerSummary(player),
63
64
                Room:    int(lobby.ID),
65
                Message: message,
66
                InGame:  true,
67
        }
68
}
func Lobby.SetState
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

291
func (l *Lobby) SetState(s LobbyState) {
292
        db.DB.Table("lobbies").Where("id = ?", l.ID).UpdateColumn("state", s)
293
}
func Say
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/pauling.go:

63
func Say(lobbyId uint, text string) {
64
        pauling.Call("Pauling.Say", &Args{Id: lobbyId, Text: text}, &Args{})
65
}
func LobbyData.SendToPlayer
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby_decorators.go:

206
func (l LobbyData) SendToPlayer(steamid string) {
207
        broadcaster.SendMessage(steamid, "lobbyData", l)
208
}
func BroadcastLobbyToUser
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

791
func BroadcastLobbyToUser(lobby *Lobby, steamid string) {
792
        //db.DB.Preload("Spectators").First(&lobby, lobby.ID)
793
        broadcaster.SendMessage(steamid, "lobbyData", DecorateLobbyData(lobby, true))
794
}
func Lobby.LobbyData
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

803
func (l *Lobby) LobbyData(include bool) LobbyData {
804
        return DecorateLobbyData(l, include)
805
}
func DecorateLobbyJoin
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby_decorators.go:

239
func DecorateLobbyJoin(lobby *Lobby) LobbyEvent {
240
        return LobbyEvent{lobby.ID}
241
}
func Lobby.ReadyUpTimeLeft
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

601
func (lobby *Lobby) ReadyUpTimeLeft() int64 {
602
        return int64(lobby.ReadyUpTimestamp - time.Now().Unix())
603
}
func Lobby.IsFull
Back

In /home/ubuntu/.go_project/src/github.com/TF2Stadium/Helen/models/lobby.go:

647
func (lobby *Lobby) IsFull() bool {
648
        return lobby.GetPlayerNumber() == 2*NumberOfClassesMap[lobby.Type]
649
}
github.com/TF2Stadium/Helen/models
66.97%