diff --git a/server/player/chat/translate.go b/server/player/chat/translate.go index 4beae2c16..4c016cdd2 100644 --- a/server/player/chat/translate.go +++ b/server/player/chat/translate.go @@ -75,15 +75,15 @@ func (t Translation) Resolve(l language.Tag) string { // F takes arguments for a translation string passed and returns a filled out // translation that may be sent to players. The number of arguments passed must // be exactly equal to the number specified in Translate. If not, F will panic. +// Arguments passed are converted to strings using fmt.Sprint(). Exceptions are +// made for argument values of the type TranslationString, Translation and +// translation, which are resolved based on the Translator's language. +// Translations used as arguments should not require any parameters. func (t Translation) F(a ...any) translation { if len(a) != t.params { panic(fmt.Sprintf("translation '%v' requires exactly %v parameters, got %v", t.format, t.params, len(a))) } - params := make([]string, len(a)) - for i, arg := range a { - params[i] = fmt.Sprint(arg) - } - return translation{t: t, params: params, fallbackParams: a} + return translation{t: t, params: a} } // translation is a translation string with its arguments filled out. Resolve may @@ -91,9 +91,8 @@ func (t Translation) F(a ...any) translation { // Params may be called to obtain the parameters passed in Translation.F. // translation implements the fmt.Stringer and error interfaces. type translation struct { - t Translation - params []string - fallbackParams []any + t Translation + params []any } // Resolve translates the TranslationString of the translation to the language @@ -104,13 +103,21 @@ func (t translation) Resolve(l language.Tag) string { // Params returns a slice of values that are used to parameterise the // translation returned by Resolve. -func (t translation) Params() []string { - return t.params +func (t translation) Params(l language.Tag) []string { + params := make([]string, len(t.params)) + for i, arg := range t.params { + if str, ok := arg.(TranslationString); ok { + params[i] = str.Resolve(l) + continue + } + params[i] = fmt.Sprint(arg) + } + return params } // String formats and returns the fallback value of the translation. func (t translation) String() string { - return fmt.Sprintf(text.Colourf(t.t.format, t.t.fallback), t.fallbackParams...) + return fmt.Sprintf(text.Colourf(t.t.format, t.t.fallback), t.params...) } // Error formats and returns the fallback value of the translation. diff --git a/server/session/command.go b/server/session/command.go index b2c24702b..644a94d73 100644 --- a/server/session/command.go +++ b/server/session/command.go @@ -19,14 +19,14 @@ func (s *Session) SendCommandOutput(output *cmd.Output, l language.Tag) { for _, message := range output.Messages() { om := protocol.CommandOutputMessage{Success: true, Message: message.String()} if t, ok := message.(translation); ok { - om.Message, om.Parameters = t.Resolve(l), t.Params() + om.Message, om.Parameters = t.Resolve(l), t.Params(l) } messages = append(messages, om) } for _, err := range output.Errors() { om := protocol.CommandOutputMessage{Message: err.Error()} if t, ok := err.(translation); ok { - om.Message, om.Parameters = t.Resolve(l), t.Params() + om.Message, om.Parameters = t.Resolve(l), t.Params(l) } messages = append(messages, om) } @@ -41,7 +41,7 @@ func (s *Session) SendCommandOutput(output *cmd.Output, l language.Tag) { type translation interface { Resolve(l language.Tag) string - Params() []string + Params(l language.Tag) []string } // sendAvailableCommands sends all available commands of the server. Once sent, they will be visible in the diff --git a/server/session/text.go b/server/session/text.go index fa59b189e..f1fe077c5 100644 --- a/server/session/text.go +++ b/server/session/text.go @@ -24,7 +24,7 @@ func (s *Session) SendTranslation(t chat.Translation, l language.Tag, a []any) { TextType: packet.TextTypeTranslation, NeedsTranslation: true, Message: tr.Resolve(l), - Parameters: tr.Params(), + Parameters: tr.Params(l), }) }