822 lines
24 KiB
Go
822 lines
24 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"math/rand"
|
|
"os"
|
|
"path/filepath"
|
|
"slices"
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type JumpDatabaseMapEntry struct {
|
|
Authors []struct {
|
|
Name string `json:"name"`
|
|
Player struct {
|
|
SteamID string `json:"steamId"`
|
|
Country string `json:"country"`
|
|
} `json:"player"`
|
|
} `json:"authors"`
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Videos struct {
|
|
Soldier string `json:"soldier"`
|
|
Demoman string `json:"demoman"`
|
|
} `json:"videos"`
|
|
Tiers struct {
|
|
Soldier int `json:"soldier"`
|
|
Demoman int `json:"demoman"`
|
|
} `json:"tiers"`
|
|
Zones struct {
|
|
Bonus []struct {
|
|
ID int `json:"id"`
|
|
Map struct {
|
|
Tiers struct {
|
|
Soldier int `json:"soldier"`
|
|
Demoman int `json:"demoman"`
|
|
} `json:"tiers"`
|
|
} `json:"map"`
|
|
Type string `json:"type"`
|
|
Zoneindex int `json:"zoneindex"`
|
|
CustomName any `json:"customName"`
|
|
} `json:"bonus"`
|
|
BonusEnd []struct {
|
|
ID int `json:"id"`
|
|
Map struct {
|
|
Tiers struct {
|
|
Soldier int `json:"soldier"`
|
|
Demoman int `json:"demoman"`
|
|
} `json:"tiers"`
|
|
} `json:"map"`
|
|
Type string `json:"type"`
|
|
Zoneindex int `json:"zoneindex"`
|
|
CustomName any `json:"customName"`
|
|
} `json:"bonusEnd"`
|
|
Checkpoint []struct {
|
|
ID int `json:"id"`
|
|
Map struct {
|
|
Tiers struct {
|
|
Soldier int `json:"soldier"`
|
|
Demoman int `json:"demoman"`
|
|
} `json:"tiers"`
|
|
} `json:"map"`
|
|
Type string `json:"type"`
|
|
Zoneindex int `json:"zoneindex"`
|
|
CustomName any `json:"customName"`
|
|
} `json:"checkpoint"`
|
|
Course []struct {
|
|
ID int `json:"id"`
|
|
Map struct {
|
|
Tiers struct {
|
|
Soldier int `json:"soldier"`
|
|
Demoman int `json:"demoman"`
|
|
} `json:"tiers"`
|
|
} `json:"map"`
|
|
Type string `json:"type"`
|
|
Zoneindex int `json:"zoneindex"`
|
|
CustomName string `json:"customName"`
|
|
} `json:"course"`
|
|
CourseEnd []struct {
|
|
ID int `json:"id"`
|
|
Map struct {
|
|
Tiers struct {
|
|
Soldier int `json:"soldier"`
|
|
Demoman int `json:"demoman"`
|
|
} `json:"tiers"`
|
|
} `json:"map"`
|
|
Type string `json:"type"`
|
|
Zoneindex int `json:"zoneindex"`
|
|
CustomName any `json:"customName"`
|
|
} `json:"courseEnd"`
|
|
Linear []any `json:"linear"`
|
|
Map []struct {
|
|
ID int `json:"id"`
|
|
Map struct {
|
|
Tiers struct {
|
|
Soldier int `json:"soldier"`
|
|
Demoman int `json:"demoman"`
|
|
} `json:"tiers"`
|
|
} `json:"map"`
|
|
Type string `json:"type"`
|
|
Zoneindex int `json:"zoneindex"`
|
|
CustomName any `json:"customName"`
|
|
} `json:"map"`
|
|
MapEnd []struct {
|
|
ID int `json:"id"`
|
|
Map struct {
|
|
Tiers struct {
|
|
Soldier int `json:"soldier"`
|
|
Demoman int `json:"demoman"`
|
|
} `json:"tiers"`
|
|
} `json:"map"`
|
|
Type string `json:"type"`
|
|
Zoneindex int `json:"zoneindex"`
|
|
CustomName any `json:"customName"`
|
|
} `json:"mapEnd"`
|
|
Misc []struct {
|
|
ID int `json:"id"`
|
|
Map struct {
|
|
Tiers struct {
|
|
Soldier int `json:"soldier"`
|
|
Demoman int `json:"demoman"`
|
|
} `json:"tiers"`
|
|
} `json:"map"`
|
|
Type string `json:"type"`
|
|
Zoneindex int `json:"zoneindex"`
|
|
CustomName string `json:"customName"`
|
|
} `json:"misc"`
|
|
Trick []struct {
|
|
ID int `json:"id"`
|
|
Map struct {
|
|
Tiers struct {
|
|
Soldier int `json:"soldier"`
|
|
Demoman int `json:"demoman"`
|
|
} `json:"tiers"`
|
|
} `json:"map"`
|
|
Type string `json:"type"`
|
|
Zoneindex int `json:"zoneindex"`
|
|
CustomName string `json:"customName"`
|
|
} `json:"trick"`
|
|
} `json:"zones"`
|
|
}
|
|
|
|
type PreviousRun struct {
|
|
Duration float64 `json:"duration"`
|
|
Date float64 `json:"date"`
|
|
}
|
|
|
|
type JumpmapRunTimeEntry struct {
|
|
Nontempusrun bool `json:"nontempusrun"`
|
|
ManuallyCreated bool `json:"manually_created"`
|
|
ID int `json:"id"`
|
|
Duration float64 `json:"duration"`
|
|
Rank int `json:"rank"`
|
|
Date float64 `json:"date"`
|
|
Class string `json:"class"`
|
|
Name string `json:"name"`
|
|
PreviousRuns []PreviousRun `json:"previous_runs"`
|
|
}
|
|
|
|
func check(e error) {
|
|
if e != nil {
|
|
panic(e)
|
|
}
|
|
}
|
|
|
|
func CreateBaseRunTimeEntry(jump_map_name string) JumpmapRunTimeEntry {
|
|
base_entry_str := `{
|
|
"nontempusrun": true,
|
|
"manually_created": true,
|
|
"id": -1,
|
|
"duration": 0,
|
|
"rank": -1,
|
|
"date": 0,
|
|
"class": "SOLDIER",
|
|
"name": "jump_basejson"
|
|
}`
|
|
|
|
var jump_map JumpmapRunTimeEntry
|
|
if err := json.Unmarshal([]byte(base_entry_str), &jump_map); err != nil {
|
|
check(err)
|
|
}
|
|
jump_map.Name = jump_map_name
|
|
return jump_map
|
|
}
|
|
|
|
func ConvertPrettyTimeToSeconds(time string) float64 {
|
|
parts := strings.Split(time, ":")
|
|
seconds := 0.0
|
|
|
|
if len(parts) == 1 {
|
|
secs, _ := strconv.ParseFloat(parts[0], 64)
|
|
seconds += secs
|
|
} else if len(parts) == 2 {
|
|
minutes, _ := strconv.ParseFloat(parts[0], 64)
|
|
secs, _ := strconv.ParseFloat(parts[1], 64)
|
|
seconds += minutes*60 + secs
|
|
} else if len(parts) == 3 {
|
|
hours, _ := strconv.ParseFloat(parts[0], 64)
|
|
minutes, _ := strconv.ParseFloat(parts[1], 64)
|
|
secs, _ := strconv.ParseFloat(parts[2], 64)
|
|
seconds += hours*3600 + minutes*60 + secs
|
|
} else if len(parts) == 4 {
|
|
days, _ := strconv.ParseFloat(parts[0], 64)
|
|
hours, _ := strconv.ParseFloat(parts[1], 64)
|
|
minutes, _ := strconv.ParseFloat(parts[2], 64)
|
|
secs, _ := strconv.ParseFloat(parts[3], 64)
|
|
seconds += days*86400 + hours*3600 + minutes*60 + secs
|
|
}
|
|
return seconds
|
|
}
|
|
|
|
func ExtractBareFilenameFromPath(in_path string) string {
|
|
baseName := filepath.Base(in_path)
|
|
lastDotIndex := strings.LastIndex(baseName, ".")
|
|
if lastDotIndex != -1 {
|
|
fileNameWithoutExt := baseName[:lastDotIndex]
|
|
return fileNameWithoutExt
|
|
} else {
|
|
// If there's no extension, the whole base name is the filename
|
|
return baseName
|
|
}
|
|
}
|
|
|
|
/*func RemoveElement(slice []any, s int) []any {
|
|
return append(slice[:s], slice[s+1:]...)
|
|
}*/
|
|
|
|
func GetCurtime() float64 {
|
|
currentTime := time.Now()
|
|
fractional_nanosecond := float64(currentTime.UnixNano())
|
|
unix_seconds := fractional_nanosecond / 1e9
|
|
return unix_seconds
|
|
}
|
|
|
|
const (
|
|
JumpmapTypeSoldier = 0
|
|
JumpmapTypeDemoman = 1
|
|
)
|
|
|
|
func GetFileNameFromJumpmapRunTypeEnum(run_type int) string {
|
|
if run_type == JumpmapTypeSoldier {
|
|
return "soldier"
|
|
}
|
|
if run_type == JumpmapTypeDemoman {
|
|
return "demoman"
|
|
}
|
|
panic("unknown jumpmap run types!")
|
|
// return "unknown"
|
|
}
|
|
|
|
func StringToJumpmapRunType(jump_map_wanted_type string) int {
|
|
switch jump_map_wanted_type {
|
|
case "s":
|
|
fallthrough
|
|
case "soldier":
|
|
return JumpmapTypeSoldier
|
|
case "d":
|
|
fallthrough
|
|
case "demoman":
|
|
return JumpmapTypeDemoman
|
|
default:
|
|
}
|
|
panic("Trying to convert to jumpmap run type (soldier/demo) with incorrect string data!")
|
|
}
|
|
|
|
var mapinfo_database_location = filepath.Join("database", "map_info")
|
|
|
|
func GetDatabaseFilePath(jump_map_name string) string {
|
|
return filepath.Join(mapinfo_database_location, jump_map_name+".json")
|
|
}
|
|
|
|
func GetRecordFilePath(jump_map_type int, jump_map_name string) string {
|
|
return filepath.Join("personal", "completed."+GetFileNameFromJumpmapRunTypeEnum(jump_map_type), jump_map_name+".json")
|
|
}
|
|
|
|
func ReadDatabaseFile(jump_map_name string) JumpDatabaseMapEntry {
|
|
data, error := os.ReadFile(GetDatabaseFilePath(jump_map_name))
|
|
check(error)
|
|
|
|
var jump_map JumpDatabaseMapEntry
|
|
if err := json.Unmarshal(data, &jump_map); err != nil {
|
|
check(err)
|
|
}
|
|
|
|
if jump_map.Name != ExtractBareFilenameFromPath(jump_map_name) {
|
|
panic("Malformed Map Database entry: " + jump_map_name + " Has: " + jump_map.Name)
|
|
}
|
|
|
|
return jump_map
|
|
}
|
|
|
|
func ReadRunRecordFile(jump_map_type int, jump_map_name string) JumpmapRunTimeEntry {
|
|
data, error := os.ReadFile(GetRecordFilePath(jump_map_type, jump_map_name))
|
|
check(error)
|
|
|
|
var jump_map JumpmapRunTimeEntry
|
|
if err := json.Unmarshal(data, &jump_map); err != nil {
|
|
check(err)
|
|
}
|
|
|
|
if jump_map.Name != ExtractBareFilenameFromPath(jump_map_name) {
|
|
panic("Malformed Run Record: " + jump_map_name + " Has: " + jump_map.Name)
|
|
}
|
|
|
|
return jump_map
|
|
}
|
|
|
|
func SubmitNewTime(jump_map_type int, jump_map_name string, duration float64) {
|
|
record_filepath := GetRecordFilePath(jump_map_type, jump_map_name)
|
|
|
|
var new_entry JumpmapRunTimeEntry
|
|
// Try to read the file firs
|
|
_, err := os.Stat(record_filepath)
|
|
run_exists := err == nil
|
|
if run_exists {
|
|
// if it exists, read it and verify run is fast
|
|
new_entry = ReadRunRecordFile(jump_map_type, jump_map_name)
|
|
if duration >= new_entry.Duration {
|
|
if new_entry.Duration == duration {
|
|
fmt.Printf("Time is duplicate or the same as current time: %f - %s\n", new_entry.Duration, jump_map_name+": "+GetPrettyTime(new_entry.Duration))
|
|
} else {
|
|
how_slow := (new_entry.Duration - duration)
|
|
fmt.Printf("Time is too slow by %f seconds: %s\n", how_slow, jump_map_name)
|
|
fmt.Printf("Get Faster by: %s\n", GetPrettyTime(how_slow))
|
|
}
|
|
panic("Time too slow!!! Get faster then try again.")
|
|
}
|
|
|
|
// back it up
|
|
ConvertRunToPrevious := func(new_entry JumpmapRunTimeEntry) PreviousRun {
|
|
var prev_run PreviousRun
|
|
prev_run.Date = new_entry.Date
|
|
prev_run.Duration = new_entry.Duration
|
|
return prev_run
|
|
}
|
|
new_entry.PreviousRuns = append(new_entry.PreviousRuns, ConvertRunToPrevious(new_entry))
|
|
|
|
// Create a fresh database entry
|
|
} else {
|
|
new_entry = CreateBaseRunTimeEntry(jump_map_name)
|
|
}
|
|
|
|
// Set the time within the record
|
|
new_entry.Duration = duration
|
|
new_entry.Date = GetCurtime()
|
|
|
|
// Assemble and Write it to a file
|
|
json_file_data, err := json.MarshalIndent(new_entry, "", "\t")
|
|
check(err)
|
|
err = os.WriteFile(record_filepath, json_file_data, 0777)
|
|
check(err)
|
|
|
|
fmt.Println("Submitted NEW time for map: " + jump_map_name)
|
|
}
|
|
|
|
func PrintRecord(printable_record any) string {
|
|
data, error := json.MarshalIndent(printable_record, "", "\t")
|
|
check(error)
|
|
return string(data)
|
|
}
|
|
|
|
func DoesFileExist(filepath string) bool {
|
|
if _, err := os.Stat(filepath); err == nil {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func FindMapNameFromPartial(partial_jump_map_name string) string {
|
|
if !strings.HasPrefix(partial_jump_map_name, "jump_") && !strings.HasPrefix(partial_jump_map_name, "rj_") {
|
|
partial_jump_map_name = "jump_" + partial_jump_map_name
|
|
}
|
|
|
|
found_files, err := filepath.Glob(GetDatabaseFilePath(partial_jump_map_name + "*"))
|
|
check(err)
|
|
found_file_count := len(found_files)
|
|
if found_file_count > 1 {
|
|
found_map := GetDatabaseFilePath(partial_jump_map_name)
|
|
if DoesFileExist(found_map) {
|
|
return ExtractBareFilenameFromPath(found_map)
|
|
} else {
|
|
fmt.Printf("There are too many maps that match your request: \"%s\"\n", partial_jump_map_name)
|
|
if found_file_count < 5 {
|
|
fmt.Println("The following maps match your request:")
|
|
fmt.Println(strings.Join(found_files, "\n"))
|
|
}
|
|
os.Exit(2)
|
|
}
|
|
}
|
|
if len(found_files) == 0 {
|
|
fmt.Println("Unable to find mapname: " + partial_jump_map_name)
|
|
panic("Attempting to find map that doesnt exist: " + partial_jump_map_name)
|
|
}
|
|
// should be just one
|
|
return ExtractBareFilenameFromPath(found_files[0])
|
|
}
|
|
|
|
func GetPrettyTime(in_time float64) string {
|
|
duration := time.Duration(in_time) * time.Second
|
|
hours := int(duration.Hours())
|
|
minutes := int(duration.Minutes()) % 60
|
|
seconds := int(duration.Seconds()) % 60
|
|
return fmt.Sprintf("%dh %dm %ds", hours, minutes, seconds)
|
|
}
|
|
|
|
func GetPrettyMapTime(jump_map_type int, jump_map_name string) string {
|
|
run_record := ReadRunRecordFile(jump_map_type, jump_map_name)
|
|
return GetPrettyTime(run_record.Duration)
|
|
}
|
|
|
|
func GetMapList() []string {
|
|
found_files, err := filepath.Glob(filepath.Join(mapinfo_database_location, "*.json"))
|
|
check(err)
|
|
for index, fle := range found_files {
|
|
found_files[index] = ExtractBareFilenameFromPath(fle)
|
|
}
|
|
return found_files
|
|
}
|
|
|
|
func GetCompletedMapList(jump_map_type int) []string {
|
|
found_files, err := filepath.Glob(filepath.Join("personal", "completed."+GetFileNameFromJumpmapRunTypeEnum(jump_map_type), "*.json"))
|
|
check(err)
|
|
for index, fle := range found_files {
|
|
found_files[index] = ExtractBareFilenameFromPath(fle)
|
|
}
|
|
return found_files
|
|
}
|
|
|
|
func GetMapTier(jump_map_type int, jump_map_name string) int {
|
|
map_info := ReadDatabaseFile(jump_map_name)
|
|
tier := func() int {
|
|
switch jump_map_type {
|
|
case JumpmapTypeDemoman:
|
|
return map_info.Tiers.Demoman
|
|
case JumpmapTypeSoldier:
|
|
return map_info.Tiers.Soldier
|
|
default:
|
|
panic("unselectable JumpmapType enum option other than solly or demo")
|
|
}
|
|
}()
|
|
return tier
|
|
}
|
|
|
|
func IsOnMapIgnorelist(jump_map_name string) bool {
|
|
if jump_map_name == "base_jump" {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func PrintMapRuntime(jump_map_type int, jump_map_name string) {
|
|
fmt.Println("Run time for " + jump_map_name + ": " + GetPrettyMapTime(jump_map_type, jump_map_name))
|
|
}
|
|
|
|
func PrintUsageInfo() {
|
|
fmt.Println("usage: " + os.Args[0] + " [operation] <Additional Args>")
|
|
fmt.Println("try running \"" + os.Args[0] + " help\" for additional info on operations")
|
|
}
|
|
|
|
func PrintMapUsageInfo() {
|
|
fmt.Println("usage: " + os.Args[0] + " [operation] <MAP_NAME> <SOLDIER/DEMOMAN(s/d)>")
|
|
}
|
|
|
|
func PrintClassUsageInfo() {
|
|
fmt.Println("usage: " + os.Args[0] + " [operation] <SOLDIER/DEMOMAN(s/d)>")
|
|
}
|
|
|
|
func PrintSubmitTimeInfo() {
|
|
fmt.Println("usage: " + os.Args[0] + " [operation] <MAP_NAME> <TIME> <SOLDIER/DEMOMAN(s/d)>")
|
|
fmt.Println("Format the time as follows: HH:MM:SS.MS")
|
|
}
|
|
|
|
func PrintHelpInfo() {
|
|
PrintUsageInfo()
|
|
fmt.Println("help - Get the help you are currently seeing")
|
|
fmt.Println("list-maps - Get a list of all maps available")
|
|
fmt.Println("get-curtime - Get the current unix date, time in seconds, for use in storing times in the database")
|
|
fmt.Println("convert-time - Convert a time from HH:MM:SS.MS to seconds, for use in storing times in the database")
|
|
fmt.Println("")
|
|
|
|
PrintMapUsageInfo()
|
|
fmt.Println("get-time - Get a personal maps completion time")
|
|
fmt.Println("list-tier - Get the difficulty tier of a particular map")
|
|
fmt.Println("")
|
|
|
|
PrintClassUsageInfo()
|
|
fmt.Println("list-tiers - Get all of the difficulty tiers listed out, useful for combining with grep!")
|
|
fmt.Println("list-completed-tiers - List out personal completed maps with their tiers")
|
|
fmt.Println("list-uncompleted-tiers - List out personal unbeaten maps with their tiers, useful for combining with grep!")
|
|
fmt.Println("list-completed-times - Lists out the completed maps with their times sorted by the time with newest first.")
|
|
fmt.Println("list-old-completed-times - Lists out the completed maps with their times sorted by the time with oldest first.")
|
|
fmt.Println("list-recently-completed-times - Lists out the last 6 maps completed.")
|
|
fmt.Println("list-few-old-completed-times - Lists out the 6 maps with the oldest completion time.")
|
|
fmt.Println("list-uncompleted-random/list-handful - Lists out the 6 maps to play that you havent completed or are very old, within a low tier if difficulty")
|
|
fmt.Println("")
|
|
|
|
PrintSubmitTimeInfo()
|
|
fmt.Println("submit-time - Submit a run, will create a file or will read the file and verify it then backup the run and submit if better")
|
|
fmt.Println("")
|
|
}
|
|
|
|
func main() {
|
|
argument_length := len(os.Args)
|
|
if argument_length < 2 {
|
|
PrintUsageInfo()
|
|
os.Exit(42)
|
|
}
|
|
|
|
ParseMapArgs := func() (int, string) {
|
|
if argument_length < 3 {
|
|
fmt.Println("Error: No map name provided")
|
|
PrintMapUsageInfo()
|
|
os.Exit(1)
|
|
}
|
|
wanted_class := JumpmapTypeSoldier
|
|
if argument_length < 4 {
|
|
fmt.Println("Warning: No classname provided, using soldier as default")
|
|
} else {
|
|
wanted_class = StringToJumpmapRunType(os.Args[3])
|
|
}
|
|
// try {
|
|
wanted_map := FindMapNameFromPartial(os.Args[2])
|
|
return wanted_class, wanted_map
|
|
}
|
|
ParseClassArgs := func() int {
|
|
wanted_class := JumpmapTypeSoldier
|
|
if argument_length < 3 {
|
|
fmt.Println("Warning: No classname provided, using soldier as default")
|
|
} else {
|
|
wanted_class = StringToJumpmapRunType(os.Args[2])
|
|
}
|
|
return wanted_class
|
|
}
|
|
|
|
switch os.Args[1] {
|
|
case "help":
|
|
PrintHelpInfo()
|
|
case "list-maps":
|
|
map_list := GetMapList()
|
|
fmt.Println("Found maps:")
|
|
for _, mapp := range map_list {
|
|
fmt.Println(mapp)
|
|
}
|
|
case "get-curtime":
|
|
fmt.Printf("Curtime: %f\n", GetCurtime())
|
|
case "convert-time":
|
|
if argument_length < 3 {
|
|
fmt.Println("Error: No time to convert into seconds???...???")
|
|
os.Exit(1)
|
|
}
|
|
fmt.Printf("Converted-Time-To-Seconds: %f\n", ConvertPrettyTimeToSeconds(os.Args[2]))
|
|
|
|
case "get-time":
|
|
wanted_class, wanted_map := ParseMapArgs()
|
|
PrintMapRuntime(wanted_class, wanted_map)
|
|
case "list-tier":
|
|
wanted_class, wanted_map := ParseMapArgs()
|
|
fmt.Printf("%s: T%d\n", wanted_map, GetMapTier(wanted_class, wanted_map))
|
|
|
|
case "list-tiers":
|
|
wanted_class := ParseClassArgs()
|
|
|
|
map_list := GetMapList()
|
|
fmt.Println("Found map tiers:")
|
|
for _, mapp := range map_list {
|
|
fmt.Printf("%s: T%d\n", mapp, GetMapTier(wanted_class, mapp))
|
|
}
|
|
|
|
case "list-completed-tiers":
|
|
wanted_class := ParseClassArgs()
|
|
|
|
map_list := GetCompletedMapList(wanted_class)
|
|
fmt.Println("Found completed map tiers:")
|
|
for _, mapp := range map_list {
|
|
if !IsOnMapIgnorelist(mapp) {
|
|
fmt.Printf("%s: T%d\n", mapp, GetMapTier(wanted_class, mapp))
|
|
}
|
|
}
|
|
|
|
case "list-uncompleted-tiers":
|
|
wanted_class := ParseClassArgs()
|
|
|
|
map_list := GetMapList()
|
|
completed_map_list := GetCompletedMapList(wanted_class)
|
|
fmt.Println("Found uncompleted map tiers:")
|
|
for _, mapp := range map_list {
|
|
if !slices.Contains(completed_map_list, mapp) {
|
|
fmt.Printf("%s: T%d\n", mapp, GetMapTier(wanted_class, mapp))
|
|
}
|
|
}
|
|
|
|
case "list-completed-times":
|
|
wanted_class := ParseClassArgs()
|
|
|
|
// map_list := GetMapList()
|
|
completed_map_list := GetCompletedMapList(wanted_class)
|
|
|
|
// Read in all completion records!
|
|
var records []JumpmapRunTimeEntry
|
|
for _, mapp := range completed_map_list {
|
|
if !IsOnMapIgnorelist(mapp) {
|
|
run_record := ReadRunRecordFile(wanted_class, mapp)
|
|
records = append(records, run_record)
|
|
}
|
|
}
|
|
|
|
// Sort
|
|
sort.Slice(records, func(i, j int) bool {
|
|
return records[i].Date > records[j].Date
|
|
})
|
|
|
|
fmt.Println("Completed Maps:")
|
|
for _, mapp := range records {
|
|
fmt.Printf("%s: Completed: %s in %s\n", mapp.Name, time.Unix(int64(mapp.Date), 0).Format("2006-01-02/15:04"), GetPrettyMapTime(wanted_class, mapp.Name))
|
|
}
|
|
|
|
case "list-recently-completed-times":
|
|
wanted_class := ParseClassArgs()
|
|
|
|
// map_list := GetMapList()
|
|
completed_map_list := GetCompletedMapList(wanted_class)
|
|
|
|
// Read in all completion records!
|
|
var records []JumpmapRunTimeEntry
|
|
for _, mapp := range completed_map_list {
|
|
if !IsOnMapIgnorelist(mapp) {
|
|
run_record := ReadRunRecordFile(wanted_class, mapp)
|
|
records = append(records, run_record)
|
|
}
|
|
}
|
|
|
|
// Sort
|
|
sort.Slice(records, func(i, j int) bool {
|
|
return records[i].Date > records[j].Date
|
|
})
|
|
|
|
fmt.Println("Recently Completed Maps:")
|
|
for i, mapp := range records {
|
|
fmt.Printf("%s: Completed: %s in %s\n", mapp.Name, time.Unix(int64(mapp.Date), 0).Format("2006-01-02/15:04"), GetPrettyMapTime(wanted_class, mapp.Name))
|
|
if i >= 6 {
|
|
break
|
|
}
|
|
}
|
|
|
|
case "list-old-completed-times":
|
|
wanted_class := ParseClassArgs()
|
|
|
|
// map_list := GetMapList()
|
|
completed_map_list := GetCompletedMapList(wanted_class)
|
|
|
|
// Read in all completion records!
|
|
var records []JumpmapRunTimeEntry
|
|
for _, mapp := range completed_map_list {
|
|
if !IsOnMapIgnorelist(mapp) {
|
|
run_record := ReadRunRecordFile(wanted_class, mapp)
|
|
records = append(records, run_record)
|
|
}
|
|
}
|
|
|
|
// Sort
|
|
sort.Slice(records, func(i, j int) bool {
|
|
return records[i].Date < records[j].Date
|
|
})
|
|
|
|
fmt.Println("Old Completed Maps:")
|
|
for _, mapp := range records {
|
|
fmt.Printf("%s: Completed: %s in %s\n", mapp.Name, time.Unix(int64(mapp.Date), 0).Format("2006-01-02/15:04"), GetPrettyMapTime(wanted_class, mapp.Name))
|
|
}
|
|
|
|
case "list-few-old-completed-times":
|
|
wanted_class := ParseClassArgs()
|
|
|
|
// map_list := GetMapList()
|
|
completed_map_list := GetCompletedMapList(wanted_class)
|
|
|
|
// Read in all completion records!
|
|
var records []JumpmapRunTimeEntry
|
|
for _, mapp := range completed_map_list {
|
|
if !IsOnMapIgnorelist(mapp) {
|
|
run_record := ReadRunRecordFile(wanted_class, mapp)
|
|
records = append(records, run_record)
|
|
}
|
|
}
|
|
|
|
// Sort
|
|
sort.Slice(records, func(i, j int) bool {
|
|
return records[i].Date < records[j].Date
|
|
})
|
|
|
|
fmt.Println("Oldest Completed Maps:")
|
|
for i, mapp := range records {
|
|
fmt.Printf("%s: Completed: %s in %s\n", mapp.Name, time.Unix(int64(mapp.Date), 0).Format("2006-01-02/15:04"), GetPrettyMapTime(wanted_class, mapp.Name))
|
|
if i >= 6 {
|
|
break
|
|
}
|
|
}
|
|
|
|
case "list-uncompleted-random":
|
|
fallthrough
|
|
case "list-handful":
|
|
wanted_class := ParseClassArgs()
|
|
|
|
map_list := GetMapList()
|
|
completed_map_list := GetCompletedMapList(wanted_class)
|
|
|
|
// Gather Tier 1-3 (Easy Stuff) and 15% of the total number of the tier below its maps... eventually...
|
|
var mapinfo_pool []string
|
|
var tier_three_count int
|
|
for _, mapp := range map_list {
|
|
if slices.Contains(completed_map_list, mapp) {
|
|
continue
|
|
}
|
|
map_tier := GetMapTier(wanted_class, mapp)
|
|
if map_tier != 1 && map_tier != 2 && map_tier != 3 {
|
|
continue
|
|
}
|
|
if map_tier == 3 {
|
|
tier_three_count++
|
|
}
|
|
mapinfo_pool = append(mapinfo_pool, fmt.Sprintf("%s: T%d", mapp, map_tier))
|
|
}
|
|
// Add the 15% of Tier 4
|
|
tier_four_percentage := int(float64(tier_three_count) * 0.30)
|
|
var tier_four_mapinfo_pool []string
|
|
for _, mapp := range map_list {
|
|
if slices.Contains(completed_map_list, mapp) {
|
|
continue
|
|
}
|
|
map_tier := GetMapTier(wanted_class, mapp)
|
|
if map_tier != 4 {
|
|
continue
|
|
}
|
|
tier_four_mapinfo_pool = append(tier_four_mapinfo_pool, fmt.Sprintf("%s: T%d", mapp, map_tier))
|
|
}
|
|
rand.Shuffle(len(tier_four_mapinfo_pool), func(i, j int) {
|
|
tier_four_mapinfo_pool[i], tier_four_mapinfo_pool[j] = tier_four_mapinfo_pool[j], tier_four_mapinfo_pool[i]
|
|
})
|
|
for i, mapp := range tier_four_mapinfo_pool {
|
|
mapinfo_pool = append(mapinfo_pool, mapp)
|
|
if i >= tier_four_percentage {
|
|
break
|
|
}
|
|
}
|
|
|
|
// get 10% of the oldest and add them into the canidates
|
|
// Read in all completion records!
|
|
var records []JumpmapRunTimeEntry
|
|
for _, mapp := range completed_map_list {
|
|
if !IsOnMapIgnorelist(mapp) {
|
|
run_record := ReadRunRecordFile(wanted_class, mapp)
|
|
records = append(records, run_record)
|
|
}
|
|
}
|
|
sort.Slice(records, func(i, j int) bool {
|
|
return records[i].Date < records[j].Date
|
|
})
|
|
oldest_percentage := int(float64(len(records)) * 0.08)
|
|
for i, mapp := range records {
|
|
mapinfo_pool = append(mapinfo_pool, fmt.Sprintf("%s: Oldest Completed: %s in %s", mapp.Name, time.Unix(int64(mapp.Date), 0).Format("2006-01-02/15:04"), GetPrettyMapTime(wanted_class, mapp.Name)))
|
|
if i >= oldest_percentage {
|
|
break
|
|
}
|
|
}
|
|
|
|
// do the above with the 3% slowest times!, re-using the above record list but re-sorting and selecting from it.
|
|
sort.Slice(records, func(i, j int) bool {
|
|
return records[i].Duration > records[j].Duration
|
|
})
|
|
slowest_percentage := int(float64(len(records)) * 0.03)
|
|
for i, mapp := range records {
|
|
mapinfo_pool = append(mapinfo_pool, fmt.Sprintf("%s: Slowest Completed: %s in %s", mapp.Name, time.Unix(int64(mapp.Date), 0).Format("2006-01-02/15:04"), GetPrettyMapTime(wanted_class, mapp.Name)))
|
|
if i >= slowest_percentage {
|
|
break
|
|
}
|
|
}
|
|
|
|
// Manipulate
|
|
rand.Shuffle(len(mapinfo_pool), func(i, j int) {
|
|
mapinfo_pool[i], mapinfo_pool[j] = mapinfo_pool[j], mapinfo_pool[i]
|
|
})
|
|
|
|
// Print out
|
|
fmt.Println("Found list of maps to complete:")
|
|
for i, mapinfo_output := range mapinfo_pool {
|
|
fmt.Println(mapinfo_output)
|
|
if i >= 12 {
|
|
break
|
|
}
|
|
}
|
|
|
|
case "submit-time":
|
|
if argument_length < 3 {
|
|
fmt.Println("Error: No map name provided")
|
|
PrintSubmitTimeInfo()
|
|
os.Exit(1)
|
|
}
|
|
if argument_length < 4 {
|
|
fmt.Println("Error: No time to convert into seconds???...???")
|
|
PrintSubmitTimeInfo()
|
|
os.Exit(1)
|
|
}
|
|
wanted_class := JumpmapTypeSoldier
|
|
if argument_length < 5 {
|
|
fmt.Println("Warning: No classname provided, using soldier as default")
|
|
} else {
|
|
wanted_class = StringToJumpmapRunType(os.Args[4])
|
|
}
|
|
submitted_time := ConvertPrettyTimeToSeconds(os.Args[3])
|
|
wanted_map := FindMapNameFromPartial(os.Args[2])
|
|
|
|
SubmitNewTime(wanted_class, wanted_map, submitted_time)
|
|
PrintMapRuntime(wanted_class, wanted_map)
|
|
default:
|
|
PrintUsageInfo()
|
|
}
|
|
os.Exit(0)
|
|
}
|