Show player names in chat

This commit is contained in:
ChillerDragon 2024-06-18 13:08:56 +08:00
parent ef2c7e8a34
commit 729fe88324
5 changed files with 241 additions and 4 deletions

57
messages/game.go Normal file
View file

@ -0,0 +1,57 @@
package message
import "github.com/teeworlds-go/teeworlds/packer"
type SvClientInfo struct {
ClientId int
Local bool
Team int
Name string
Clan string
Country int
Body string
Marking string
Decoration string
Hands string
Feet string
Eyes string
CustomColorBody bool
CustomColorMarking bool
CustomColorDecoration bool
CustomColorHands bool
CustomColorFeet bool
CustomColorEyes bool
ColorBody int
ColorMarking int
ColorHands int
ColorFeet int
ColorEyes int
Silent bool
}
func (info *SvClientInfo) Unpack(u *packer.Unpacker) {
info.ClientId = u.GetInt()
info.Local = u.GetInt() != 0
info.Team = u.GetInt()
info.Name = u.GetString()
info.Clan = u.GetString()
info.Country = u.GetInt()
info.Body = u.GetString()
info.Marking = u.GetString()
info.Decoration = u.GetString()
info.Hands = u.GetString()
info.Feet = u.GetString()
info.Eyes = u.GetString()
info.CustomColorBody = u.GetInt() != 0
info.CustomColorMarking = u.GetInt() != 0
info.CustomColorDecoration = u.GetInt() != 0
info.CustomColorHands = u.GetInt() != 0
info.CustomColorFeet = u.GetInt() != 0
info.CustomColorEyes = u.GetInt() != 0
info.ColorBody = u.GetInt()
info.ColorMarking = u.GetInt()
info.ColorHands = u.GetInt()
info.ColorFeet = u.GetInt()
info.ColorEyes = u.GetInt()
info.Silent = u.GetInt() != 0
}

76
messages/game_test.go Normal file
View file

@ -0,0 +1,76 @@
package message
import (
"reflect"
"testing"
"github.com/teeworlds-go/teeworlds/packer"
)
func TestUnpackClientInfo(t *testing.T) {
u := packer.Unpacker{}
u.Reset([]byte{
0x00, 0x01, 0x00, 0x67, 0x6f, 0x70, 0x68, 0x65, 0x72, 0x00,
0x00, 0x40, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x77, 0x61, 0x72,
0x64, 0x00, 0x64, 0x75, 0x6f, 0x64, 0x6f, 0x6e, 0x6e, 0x79, 0x00,
0x00, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x00, 0x73,
0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x00, 0x73, 0x74, 0x61,
0x6e, 0x64, 0x61, 0x72, 0x64, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
0x00, 0x80, 0xfc, 0xaf, 0x05, 0xeb, 0x83, 0xd0, 0x0a, 0x80, 0xfe,
0x07, 0x80, 0xfe, 0x07, 0x80, 0xfe, 0x07, 0x80, 0xfe, 0x07, 0x00,
})
info := SvClientInfo{}
info.Unpack(&u)
{
got := info.Eyes
want := "standard"
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
got = info.Decoration
want = ""
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
got = info.Marking
want = "duodonny"
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
}
wantedInfo := SvClientInfo{
ClientId: 0,
Local: true,
Team: 0,
Name: "gopher",
Clan: "",
Country: -1,
Body: "greensward",
Marking: "duodonny",
Decoration: "",
Hands: "standard",
Feet: "standard",
Eyes: "standard",
CustomColorBody: true,
CustomColorMarking: true,
CustomColorDecoration: false,
CustomColorHands: false,
CustomColorFeet: false,
CustomColorEyes: false,
ColorBody: 5635840,
ColorMarking: -11141356,
ColorHands: 65408,
ColorFeet: 65408,
ColorEyes: 65408,
Silent: true,
}
if !reflect.DeepEqual(info, wantedInfo) {
t.Errorf("got %v, wanted %v", info, wantedInfo)
}
}

View file

@ -26,6 +26,10 @@ func (u *Unpacker) getByte() byte {
return b
}
func (u *Unpacker) Data() []byte {
return u.data
}
const (
Sanitize = 1
SanitizeCC = 2

View file

@ -5,6 +5,79 @@ import (
"testing"
)
func TestUnpackClientInfo(t *testing.T) {
u := Unpacker{}
u.Reset([]byte{
0x24, 0x00, 0x01, 0x00, 0x67, 0x6f, 0x70, 0x68, 0x65, 0x72, 0x00,
0x00, 0x40, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x77, 0x61, 0x72,
0x64, 0x00, 0x64, 0x75, 0x6f, 0x64, 0x6f, 0x6e, 0x6e, 0x79, 0x00,
0x00, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x00, 0x73,
0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x00, 0x73, 0x74, 0x61,
0x6e, 0x64, 0x61, 0x72, 0x64, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
0x00, 0x80, 0xfc, 0xaf, 0x05, 0xeb, 0x83, 0xd0, 0x0a, 0x80, 0xfe,
0x07, 0x80, 0xfe, 0x07, 0x80, 0xfe, 0x07, 0x80, 0xfe, 0x07, 0x00,
})
{
// message id
got := u.GetInt()
want := 36
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
// client id
got = u.GetInt()
want = 0
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
u.GetInt() // Local bool
u.GetInt() // Team int
}
{
// name
got := u.GetString()
want := "gopher"
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
// clan
got = u.GetString()
want = ""
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
}
{
// country
got := u.GetInt()
want := -1
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
}
{
// body
got := u.GetString()
want := "greensward"
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
}
}
// unpack with state
func TestUnpackSimpleInts(t *testing.T) {

View file

@ -11,6 +11,7 @@ import (
"github.com/teeworlds-go/huffman"
"github.com/teeworlds-go/teeworlds/chunk"
message "github.com/teeworlds-go/teeworlds/messages"
"github.com/teeworlds-go/teeworlds/packer"
"github.com/teeworlds-go/teeworlds/packet"
)
@ -18,6 +19,8 @@ import (
const (
maxPacksize = 1400
MaxClients = 64
msgCtrlKeepAlive = 0x00
msgCtrlConnect = 0x01
msgCtrlAccept = 0x02
@ -28,9 +31,10 @@ const (
msgSysConReady = 5
msgSysSnapSingle = 8
msgGameMotd = 1
msgGameSvMotd = 1
msgGameSvChat = 3
msgGameReadyToEnter = 8
msgGameSvClientInfo = 18
)
func ctrlToken(myToken []byte) []byte {
@ -67,12 +71,18 @@ func readNetwork(ch chan<- []byte, conn net.Conn) {
conn.Close()
}
type Player struct {
info message.SvClientInfo
}
type TeeworldsClient struct {
clientToken [4]byte
serverToken [4]byte
conn net.Conn
Ack int
Players []Player
}
func (client TeeworldsClient) sendCtrlMsg(data []byte) {
@ -204,20 +214,35 @@ func (client *TeeworldsClient) onSystemMsg(msg int, chunk chunk.Chunk, u *packer
}
}
func onChatMessage(mode int, clientId int, targetId int, message string) {
fmt.Printf("[chat] %d: %s\n", clientId, message)
func (client *TeeworldsClient) OnChatMessage(mode int, clientId int, targetId int, message string) {
name := client.Players[clientId].info.Name
fmt.Printf("[chat] <%s> %s\n", name, message)
}
func (client *TeeworldsClient) OnMotd(motd string) {
fmt.Printf("[motd] %s\n", motd)
}
func (client *TeeworldsClient) onGameMsg(msg int, chunk chunk.Chunk, u *packer.Unpacker) {
if msg == msgGameReadyToEnter {
fmt.Println("got ready to enter")
client.sendEnterGame()
} else if msg == msgGameSvMotd {
motd := u.GetString()
if motd != "" {
client.OnMotd(motd)
}
} else if msg == msgGameSvChat {
mode := u.GetInt()
clientId := u.GetInt()
targetId := u.GetInt()
message := u.GetString()
onChatMessage(mode, clientId, targetId, message)
client.OnChatMessage(mode, clientId, targetId, message)
} else if msg == msgGameSvClientInfo {
clientId := packer.UnpackInt(chunk.Data[1:])
client.Players[clientId].info.Unpack(u)
fmt.Printf("got client info id=%d name=%s\n", clientId, client.Players[clientId].info.Name)
} else {
fmt.Printf("unknown game message id=%d data=%x\n", msg, chunk.Data)
}
@ -309,6 +334,8 @@ func main() {
clientToken: [4]byte{0x01, 0x02, 0x03, 0x04},
serverToken: [4]byte{0xff, 0xff, 0xff, 0xff},
conn: conn,
Ack: 0,
Players: make([]Player, MaxClients),
}
go readNetwork(ch, client.conn)