github.com/df-mc/dragonfly@v0.9.13/server/player/scoreboard/scoreboard.go (about) 1 package scoreboard 2 3 import ( 4 "fmt" 5 "slices" 6 "strings" 7 ) 8 9 // Scoreboard represents a scoreboard that may be sent to a player. The scoreboard is shown on the right side 10 // of the player's screen. 11 // Scoreboard implements the io.Writer and io.StringWriter interfaces. fmt.Fprintf and fmt.Fprint may be used 12 // to write formatted text to the scoreboard. 13 type Scoreboard struct { 14 name string 15 lines []string 16 padding bool 17 } 18 19 // New returns a new scoreboard with the display name passed. Once returned, lines may be added to the 20 // scoreboard to add text to it. The name is formatted according to the rules of fmt.Sprintln. 21 // Changing the scoreboard after sending it to a player will not update the scoreboard of the player 22 // automatically: Player.SendScoreboard() must be called again to update it. 23 func New(name ...any) *Scoreboard { 24 return &Scoreboard{name: strings.TrimSuffix(fmt.Sprintln(name...), "\n"), padding: true} 25 } 26 27 // Name returns the display name of the scoreboard, as passed during the construction of the scoreboard. 28 func (board *Scoreboard) Name() string { 29 return board.name 30 } 31 32 // Write writes a slice of data as text to the scoreboard. Newlines may be written to create a new line on 33 // the scoreboard. 34 func (board *Scoreboard) Write(p []byte) (n int, err error) { 35 return board.WriteString(string(p)) 36 } 37 38 // WriteString writes a string of text to the scoreboard. Newlines may be written to create a new line on 39 // the scoreboard. 40 func (board *Scoreboard) WriteString(s string) (n int, err error) { 41 lines := strings.Split(s, "\n") 42 board.lines = append(board.lines, lines...) 43 44 // Scoreboards can have up to 15 lines. (16 including the title.) 45 if len(board.lines) >= 15 { 46 return len(lines), fmt.Errorf("write scoreboard: maximum of 15 lines of text exceeded") 47 } 48 return len(lines), nil 49 } 50 51 // Set changes a specific line in the scoreboard and adds empty lines until this index is reached. Set panics if the 52 // index passed is negative or 15+. 53 func (board *Scoreboard) Set(index int, s string) { 54 if index < 0 || index >= 15 { 55 panic(fmt.Sprintf("index out of range %v", index)) 56 } 57 if diff := index - (len(board.lines) - 1); diff > 0 { 58 board.lines = append(board.lines, make([]string, diff)...) 59 } 60 // Remove new lines from the string 61 board.lines[index] = strings.TrimSuffix(strings.TrimSuffix(s, "\n"), "\n") 62 } 63 64 // Remove removes a specific line from the scoreboard. Remove panics if the index passed is negative or 15+. 65 func (board *Scoreboard) Remove(index int) { 66 if index < 0 || index >= 15 { 67 panic(fmt.Sprintf("index out of range %v", index)) 68 } 69 board.lines = append(board.lines[:index], board.lines[index+1:]...) 70 } 71 72 // RemovePadding removes the padding of one space that is added to the start of every line. 73 func (board *Scoreboard) RemovePadding() { 74 board.padding = false 75 } 76 77 // Lines returns the data of the Scoreboard as a slice of strings. 78 func (board *Scoreboard) Lines() []string { 79 lines := slices.Clone(board.lines) 80 if board.padding { 81 for i, line := range lines { 82 if len(board.name)-len(line)-2 <= 0 { 83 lines[i] = " " + line + " " 84 continue 85 } 86 lines[i] = " " + line + strings.Repeat(" ", len(board.name)-len(line)-2) 87 } 88 } 89 return lines 90 }