package index import ( "errors" "html/template" "strings" "time" "github.com/mcstatus-io/mcutil" "github.com/mcstatus-io/mcutil/options" "github.com/mcstatus-io/mcutil/response" ) type Marshal struct { Data DataYaml Queried MC PlayersShown bool ModsShown bool ExtendedShown bool Dark bool Online bool } func (m Marshal) NewMC() (MC, error) { switch strings.ToLower(m.Data.MCType) { case "java": r, err := mcutil.Status(m.Data.MCAddress, m.Data.MCPort, options.JavaStatus{ EnableSRV: m.Data.AllowDisplayActualAddress, Timeout: m.Data.MCTimeout, ProtocolVersion: m.Data.MCProtocolVersion, }) if err != nil { return MC{}, err } r2, err := mcutil.StatusRaw(m.Data.MCAddress, m.Data.MCPort, options.JavaStatus{ EnableSRV: m.Data.AllowDisplayActualAddress, Timeout: m.Data.MCTimeout, ProtocolVersion: m.Data.MCProtocolVersion, }) if err != nil { return MC{}, err } return MC{ Timestamp: time.Now(), Version: &r.Version.NameClean, ProtocolVersion: &r.Version.Protocol, Address: m.Data.MCAddress, Port: m.Data.MCPort, Port6: nil, PlayerCount: r.Players.Online, MaxPlayers: r.Players.Max, Players: CollectPlayers(r.Players.Sample), MOTD: r.MOTD.Clean, ActualHost: CollectSRVHost(r.SRVResult), ActualPort: CollectSRVPort(r.SRVResult), Favicon: r.Favicon, Edition: CollectModEdition(r.ModInfo), ModCount: CollectModCount(r.ModInfo), Mods: CollectMods(r.ModInfo), SecureProfilesEnforced: CollectSecureProfileEnforcement(r2), PreviewChatEnforced: CollectPreviewChatEnforcement(r2), }, nil case "legacy", "legacyjava", "javalegacy", "legacy java", "java legacy", "legacy_java", "java_legacy": r, err := mcutil.StatusLegacy(m.Data.MCAddress, m.Data.MCPort, options.JavaStatusLegacy{ EnableSRV: m.Data.AllowDisplayActualAddress, Timeout: m.Data.MCTimeout, ProtocolVersion: m.Data.MCProtocolVersion, }) if err != nil { return MC{}, err } return MC{ Timestamp: time.Now(), Version: &r.Version.NameClean, ProtocolVersion: &r.Version.Protocol, Address: m.Data.MCAddress, Port: m.Data.MCPort, Port6: nil, PlayerCount: &r.Players.Online, MaxPlayers: &r.Players.Max, Players: nil, MOTD: r.MOTD.Clean, ActualHost: CollectSRVHost(r.SRVResult), ActualPort: CollectSRVPort(r.SRVResult), Favicon: nil, Edition: nil, ModCount: 0, Mods: nil, SecureProfilesEnforced: nil, PreviewChatEnforced: nil, }, nil case "bedrock": r, err := mcutil.StatusBedrock(m.Data.MCAddress, m.Data.MCPort, options.BedrockStatus{ EnableSRV: m.Data.AllowDisplayActualAddress, Timeout: m.Data.MCTimeout, ClientGUID: m.Data.MCClientGUID, }) if err != nil { return MC{}, err } return MC{ Timestamp: time.Now(), Version: r.Version, ProtocolVersion: r.ProtocolVersion, Address: m.Data.MCAddress, Port: m.CollectIPv4Port(r.PortIPv4), Port6: r.PortIPv6, PlayerCount: r.OnlinePlayers, MaxPlayers: r.MaxPlayers, Players: nil, MOTD: r.MOTD.Clean, ActualHost: CollectSRVHost(r.SRVResult), ActualPort: CollectSRVPort(r.SRVResult), Favicon: nil, Edition: r.Edition, ModCount: 0, Mods: nil, SecureProfilesEnforced: nil, PreviewChatEnforced: nil, }, nil default: return MC{}, errors.New("Invalid MCType") } } func CollectPlayers(sampleArray []response.SamplePlayer) []string { if sampleArray == nil { return nil } toReturn := make([]string, len(sampleArray)) for i := 0; i < len(sampleArray); i++ { toReturn[i] = sampleArray[i].NameClean } return toReturn } func CollectSRVHost(srv *response.SRVRecord) *string { if srv == nil { return nil } return &srv.Host } func CollectSRVPort(srv *response.SRVRecord) *uint16 { if srv == nil { return nil } return &srv.Port } func CollectModEdition(mod *response.ModInfo) *string { if mod == nil { return nil } return &mod.Type } func CollectModCount(mod *response.ModInfo) int64 { if mod == nil { return 0 } return int64(len(mod.Mods)) } func CollectMods(mod *response.ModInfo) []string { if mod == nil { return nil } toReturn := make([]string, len(mod.Mods)) for i := 0; i < len(mod.Mods); i++ { toReturn[i] = mod.Mods[i].ID + " (" + mod.Mods[i].Version + ")" } return toReturn } func CollectSecureProfileEnforcement(data map[string]interface{}) *bool { val, ok := data["enforcesSecureChat"] if ok { toReturn := val.(bool) return &toReturn } return nil } func CollectPreviewChatEnforcement(data map[string]interface{}) *bool { val, ok := data["previewsChat"] if ok { toReturn := val.(bool) return &toReturn } return nil } func (m Marshal) CollectIPv4Port(port *uint16) uint16 { if port == nil { return m.Data.MCPort } return *port } func (m *Marshal) ToggleQuery(option string) template.HTML { toReturn := "?" if (!m.Dark && option == "dark") || (m.Dark && option != "dark") { toReturn += "dark&" } if (!m.ModsShown && option == "mods") || (m.ModsShown && option != "mods") { toReturn += "mods&" } if (!m.ExtendedShown && option == "extended") || (m.ExtendedShown && option != "extended") { toReturn += "extended&" } if (!m.PlayersShown && option == "players") || (m.PlayersShown && option != "players") { toReturn += "players" } return template.HTML(strings.TrimRight(toReturn, "&")) }