From 4bb305ea6589005782fa0235423121441ad9bb92 Mon Sep 17 00:00:00 2001 From: "M. Sz" Date: Mon, 23 Nov 2020 14:18:30 +0100 Subject: [PATCH 1/4] d2networking logger --- .../d2localclient/local_client_connection.go | 7 +- .../remote_client_connection.go | 72 ++++++++++++++--- d2networking/d2client/game_client.go | 8 +- .../d2netpackettype/message_type.go | 7 +- d2networking/d2netpacket/net_packet.go | 13 ++-- d2networking/d2netpacket/packet_add_player.go | 7 +- .../d2netpacket/packet_generate_map.go | 7 +- d2networking/d2netpacket/packet_item_spawn.go | 7 +- .../d2netpacket/packet_move_player.go | 7 +- d2networking/d2netpacket/packet_ping.go | 7 +- .../d2netpacket/packet_player_cast.go | 7 +- .../packet_player_connection_request.go | 7 +- .../packet_player_disconnect_request.go | 7 +- d2networking/d2netpacket/packet_pong.go | 7 +- .../d2netpacket/packet_save_player.go | 7 +- .../d2netpacket/packet_server_closed.go | 7 +- .../d2netpacket/packet_server_full.go | 7 +- .../d2netpacket/packet_update_server_info.go | 7 +- .../udp_client_connection.go | 15 +++- d2networking/d2server/game_server.go | 77 +++++++++++++------ 20 files changed, 186 insertions(+), 104 deletions(-) diff --git a/d2networking/d2client/d2localclient/local_client_connection.go b/d2networking/d2client/d2localclient/local_client_connection.go index a1294d6c..391160b7 100644 --- a/d2networking/d2client/d2localclient/local_client_connection.go +++ b/d2networking/d2client/d2localclient/local_client_connection.go @@ -87,7 +87,12 @@ func (l *LocalClientConnection) Open(_, saveFilePath string) error { // Close disconnects from the server and destroys it. func (l *LocalClientConnection) Close() error { - err := l.SendPacketToServer(d2netpacket.CreateServerClosedPacket()) + sc, err := d2netpacket.CreateServerClosedPacket() + if err != nil { + return err + } + + err = l.SendPacketToServer(sc) if err != nil { return err } diff --git a/d2networking/d2client/d2remoteclient/remote_client_connection.go b/d2networking/d2client/d2remoteclient/remote_client_connection.go index 1fefad1f..84875a45 100644 --- a/d2networking/d2client/d2remoteclient/remote_client_connection.go +++ b/d2networking/d2client/d2remoteclient/remote_client_connection.go @@ -77,7 +77,12 @@ func (r *RemoteClientConnection) Open(connectionString, saveFilePath string) err r.Infof("Connected to server at %s", r.tcpConnection.RemoteAddr().String()) gameState := r.heroState.LoadHeroState(saveFilePath) - packet := d2netpacket.CreatePlayerConnectionRequestPacket(r.GetUniqueID(), gameState) + + packet, err := d2netpacket.CreatePlayerConnectionRequestPacket(r.GetUniqueID(), gameState) + if err != nil { + r.Errorf("PlayerConnectionRequestPacket: %v", err) + } + err = r.SendPacketToServer(packet) if err != nil { @@ -92,7 +97,13 @@ func (r *RemoteClientConnection) Open(connectionString, saveFilePath string) err // RemoteClientConnection.active to false. func (r *RemoteClientConnection) Close() error { r.active = false - err := r.SendPacketToServer(d2netpacket.CreatePlayerDisconnectRequestPacket(r.GetUniqueID())) + + pd, err := d2netpacket.CreatePlayerDisconnectRequestPacket(r.GetUniqueID()) + if err != nil { + return fmt.Errorf("PlayerDisconnectRequestPacket: %v", err) + } + + err = r.SendPacketToServer(pd) if err != nil { return err @@ -148,12 +159,12 @@ func (r *RemoteClientConnection) serverListener() { p, err := r.decodeToPacket(packet.PacketType, string(packet.PacketData)) if err != nil { - r.Error(fmt.Sprintln(packet.PacketType, err)) + r.Errorf("%v %v", packet.PacketType, err) } err = r.clientListener.OnPacketReceived(p) if err != nil { - r.Error(fmt.Sprintln(packet.PacketType, err)) + r.Errorf("%v %v", packet.PacketType, err) } } } @@ -172,7 +183,9 @@ func (r *RemoteClientConnection) bytesToJSON(buffer []byte) (string, d2netpacket // decodeToPacket unmarshals the JSON string into the correct struct // and returns a NetPacket declaring that struct. // nolint:gocyclo // switch statement on packet type makes sense, no need to change -func (r *RemoteClientConnection) decodeToPacket(t d2netpackettype.NetPacketType, data string) (d2netpacket.NetPacket, error) { +func (r *RemoteClientConnection) decodeToPacket( + t d2netpackettype.NetPacketType, + data string) (d2netpacket.NetPacket, error) { var np = d2netpacket.NetPacket{} var err error @@ -184,7 +197,12 @@ func (r *RemoteClientConnection) decodeToPacket(t d2netpackettype.NetPacketType, break } - np = d2netpacket.NetPacket{PacketType: t, PacketData: d2netpacket.MarshalPacket(p)} + mp, marshalErr := d2netpacket.MarshalPacket(p) + if marshalErr != nil { + r.Errorf("MarshalPacket: %v", marshalErr) + } + + np = d2netpacket.NetPacket{PacketType: t, PacketData: mp} case d2netpackettype.MovePlayer: var p d2netpacket.MovePlayerPacket @@ -192,7 +210,12 @@ func (r *RemoteClientConnection) decodeToPacket(t d2netpackettype.NetPacketType, break } - np = d2netpacket.NetPacket{PacketType: t, PacketData: d2netpacket.MarshalPacket(p)} + mp, marshalErr := d2netpacket.MarshalPacket(p) + if marshalErr != nil { + r.Errorf("MarshalPacket: %v", marshalErr) + } + + np = d2netpacket.NetPacket{PacketType: t, PacketData: mp} case d2netpackettype.UpdateServerInfo: var p d2netpacket.UpdateServerInfoPacket @@ -200,7 +223,12 @@ func (r *RemoteClientConnection) decodeToPacket(t d2netpackettype.NetPacketType, break } - np = d2netpacket.NetPacket{PacketType: t, PacketData: d2netpacket.MarshalPacket(p)} + mp, marshalErr := d2netpacket.MarshalPacket(p) + if marshalErr != nil { + r.Errorf("MarshalPacket: %v", marshalErr) + } + + np = d2netpacket.NetPacket{PacketType: t, PacketData: mp} case d2netpackettype.AddPlayer: var p d2netpacket.AddPlayerPacket @@ -208,7 +236,12 @@ func (r *RemoteClientConnection) decodeToPacket(t d2netpackettype.NetPacketType, break } - np = d2netpacket.NetPacket{PacketType: t, PacketData: d2netpacket.MarshalPacket(p)} + mp, marshalErr := d2netpacket.MarshalPacket(p) + if marshalErr != nil { + r.Errorf("MarshalPacket: %v", marshalErr) + } + + np = d2netpacket.NetPacket{PacketType: t, PacketData: mp} case d2netpackettype.CastSkill: var p d2netpacket.CastPacket @@ -216,7 +249,12 @@ func (r *RemoteClientConnection) decodeToPacket(t d2netpackettype.NetPacketType, break } - np = d2netpacket.NetPacket{PacketType: t, PacketData: d2netpacket.MarshalPacket(p)} + mp, marshalErr := d2netpacket.MarshalPacket(p) + if marshalErr != nil { + r.Errorf("MarshalPacket: %v", marshalErr) + } + + np = d2netpacket.NetPacket{PacketType: t, PacketData: mp} case d2netpackettype.Ping: var p d2netpacket.PingPacket @@ -224,7 +262,12 @@ func (r *RemoteClientConnection) decodeToPacket(t d2netpackettype.NetPacketType, break } - np = d2netpacket.NetPacket{PacketType: t, PacketData: d2netpacket.MarshalPacket(p)} + mp, marshalErr := d2netpacket.MarshalPacket(p) + if marshalErr != nil { + r.Errorf("MarshalPacket: %v", marshalErr) + } + + np = d2netpacket.NetPacket{PacketType: t, PacketData: mp} case d2netpackettype.PlayerDisconnectionNotification: var p d2netpacket.PlayerDisconnectRequestPacket @@ -232,7 +275,12 @@ func (r *RemoteClientConnection) decodeToPacket(t d2netpackettype.NetPacketType, break } - np = d2netpacket.NetPacket{PacketType: t, PacketData: d2netpacket.MarshalPacket(p)} + mp, marshalErr := d2netpacket.MarshalPacket(p) + if marshalErr != nil { + r.Errorf("MarshalPacket: %v", marshalErr) + } + + np = d2netpacket.NetPacket{PacketType: t, PacketData: mp} default: err = fmt.Errorf("RemoteClientConnection: unrecognized packet type: %v", t) diff --git a/d2networking/d2client/game_client.go b/d2networking/d2client/game_client.go index dab59ca1..d3b197aa 100644 --- a/d2networking/d2client/game_client.go +++ b/d2networking/d2client/game_client.go @@ -432,8 +432,12 @@ func (g *GameClient) playCastOverlay(overlayRecord *d2records.OverlayRecord, x, } func (g *GameClient) handlePingPacket() error { - pongPacket := d2netpacket.CreatePongPacket(g.PlayerID) - err := g.clientConnection.SendPacketToServer(pongPacket) + pongPacket, err := d2netpacket.CreatePongPacket(g.PlayerID) + if err != nil { + return err + } + + err = g.clientConnection.SendPacketToServer(pongPacket) if err != nil { return err diff --git a/d2networking/d2netpacket/d2netpackettype/message_type.go b/d2networking/d2netpacket/d2netpackettype/message_type.go index 70cd98a3..f7798066 100644 --- a/d2networking/d2netpacket/d2netpackettype/message_type.go +++ b/d2networking/d2netpacket/d2netpackettype/message_type.go @@ -2,7 +2,6 @@ package d2netpackettype import ( "encoding/json" - "log" ) // NetPacketType is an enum referring to all packet types in package @@ -57,11 +56,11 @@ func (n NetPacketType) String() string { } // MarshalPacket marshals the packet to a byte slice -func (n NetPacketType) MarshalPacket() []byte { +func (n NetPacketType) MarshalPacket() ([]byte, error) { p, err := json.Marshal(n) if err != nil { - log.Print(err) + return p, err } - return p + return p, nil } diff --git a/d2networking/d2netpacket/net_packet.go b/d2networking/d2netpacket/net_packet.go index bb13aeff..316e8a44 100644 --- a/d2networking/d2netpacket/net_packet.go +++ b/d2networking/d2netpacket/net_packet.go @@ -2,7 +2,6 @@ package d2netpacket import ( "encoding/json" - "log" "github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket/d2netpackettype" ) @@ -17,14 +16,14 @@ type NetPacket struct { } // InspectPacketType determines the packet type from the given data -func InspectPacketType(b []byte) d2netpackettype.NetPacketType { +func InspectPacketType(b []byte) (d2netpackettype.NetPacketType, error) { var packet NetPacket if err := json.Unmarshal(b, &packet); err != nil { - log.Println(err) + return d2netpackettype.UnknownPacketType, err } - return packet.PacketType + return packet.PacketType, nil } // UnmarshalNetPacket unmarshals the byte slice into a NetPacket struct @@ -38,11 +37,11 @@ func UnmarshalNetPacket(packet []byte) (NetPacket, error) { } // MarshalPacket is a quick helper function to Marshal very anything UNSAFELY, meaning the error is not checked before sending. -func MarshalPacket(packet interface{}) []byte { +func MarshalPacket(packet interface{}) ([]byte, error) { b, err := json.Marshal(packet) if err != nil { - log.Print(err) + return nil, err } - return b + return b, nil } diff --git a/d2networking/d2netpacket/packet_add_player.go b/d2networking/d2netpacket/packet_add_player.go index 130572ca..a503a075 100644 --- a/d2networking/d2netpacket/packet_add_player.go +++ b/d2networking/d2netpacket/packet_add_player.go @@ -2,7 +2,6 @@ package d2netpacket import ( "encoding/json" - "log" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero" @@ -37,7 +36,7 @@ func CreateAddPlayerPacket( skills map[int]*d2hero.HeroSkill, equipment d2inventory.CharacterEquipment, leftSkill, rightSkill int, - gold int) NetPacket { + gold int) (NetPacket, error) { addPlayerPacket := AddPlayerPacket{ ID: id, Name: name, @@ -54,13 +53,13 @@ func CreateAddPlayerPacket( b, err := json.Marshal(addPlayerPacket) if err != nil { - log.Print(err) + return NetPacket{PacketType: d2netpackettype.AddPlayer}, err } return NetPacket{ PacketType: d2netpackettype.AddPlayer, PacketData: b, - } + }, nil } // UnmarshalAddPlayer unmarshals the packet data into an AddPlayerPacket struct diff --git a/d2networking/d2netpacket/packet_generate_map.go b/d2networking/d2netpacket/packet_generate_map.go index 8030ea3d..2fbe4011 100644 --- a/d2networking/d2netpacket/packet_generate_map.go +++ b/d2networking/d2netpacket/packet_generate_map.go @@ -2,7 +2,6 @@ package d2netpacket import ( "encoding/json" - "log" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum" "github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket/d2netpackettype" @@ -17,20 +16,20 @@ type GenerateMapPacket struct { // CreateGenerateMapPacket returns a NetPacket which declares a // GenerateMapPacket with the given regionType. -func CreateGenerateMapPacket(regionType d2enum.RegionIdType) NetPacket { +func CreateGenerateMapPacket(regionType d2enum.RegionIdType) (NetPacket, error) { generateMapPacket := GenerateMapPacket{ RegionType: regionType, } b, err := json.Marshal(generateMapPacket) if err != nil { - log.Print(err) + return NetPacket{PacketType: d2netpackettype.GenerateMap}, err } return NetPacket{ PacketType: d2netpackettype.GenerateMap, PacketData: b, - } + }, nil } // UnmarshalGenerateMap unmarshals the given packet data into a GenerateMapPacket struct diff --git a/d2networking/d2netpacket/packet_item_spawn.go b/d2networking/d2netpacket/packet_item_spawn.go index acb24a85..1f16c0bb 100644 --- a/d2networking/d2netpacket/packet_item_spawn.go +++ b/d2networking/d2netpacket/packet_item_spawn.go @@ -2,7 +2,6 @@ package d2netpacket import ( "encoding/json" - "log" "github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket/d2netpackettype" ) @@ -16,7 +15,7 @@ type SpawnItemPacket struct { // CreateSpawnItemPacket returns a NetPacket which declares a // SpawnItemPacket with the data in given parameters. -func CreateSpawnItemPacket(x, y int, codes ...string) NetPacket { +func CreateSpawnItemPacket(x, y int, codes ...string) (NetPacket, error) { spawnItemPacket := SpawnItemPacket{ X: x, Y: y, @@ -25,13 +24,13 @@ func CreateSpawnItemPacket(x, y int, codes ...string) NetPacket { b, err := json.Marshal(spawnItemPacket) if err != nil { - log.Print(err) + return NetPacket{PacketType: d2netpackettype.SpawnItem}, err } return NetPacket{ PacketType: d2netpackettype.SpawnItem, PacketData: b, - } + }, nil } // UnmarshalSpawnItem unmarshals the given data to a SpawnItemPacket struct diff --git a/d2networking/d2netpacket/packet_move_player.go b/d2networking/d2netpacket/packet_move_player.go index 4939e1c4..9dc24b39 100644 --- a/d2networking/d2netpacket/packet_move_player.go +++ b/d2networking/d2netpacket/packet_move_player.go @@ -2,7 +2,6 @@ package d2netpacket import ( "encoding/json" - "log" "github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket/d2netpackettype" ) @@ -20,7 +19,7 @@ type MovePlayerPacket struct { // CreateMovePlayerPacket returns a NetPacket which declares a MovePlayerPacket // with the given ID and movement command. -func CreateMovePlayerPacket(playerID string, startX, startY, destX, destY float64) NetPacket { +func CreateMovePlayerPacket(playerID string, startX, startY, destX, destY float64) (NetPacket, error) { movePlayerPacket := MovePlayerPacket{ PlayerID: playerID, StartX: startX, @@ -31,13 +30,13 @@ func CreateMovePlayerPacket(playerID string, startX, startY, destX, destY float6 b, err := json.Marshal(movePlayerPacket) if err != nil { - log.Print(err) + return NetPacket{PacketType: d2netpackettype.MovePlayer}, nil } return NetPacket{ PacketType: d2netpackettype.MovePlayer, PacketData: b, - } + }, nil } // UnmarshalMovePlayer unmarshals the given data to a MovePlayerPacket struct diff --git a/d2networking/d2netpacket/packet_ping.go b/d2networking/d2netpacket/packet_ping.go index 4b13d2e2..edad91f0 100644 --- a/d2networking/d2netpacket/packet_ping.go +++ b/d2networking/d2netpacket/packet_ping.go @@ -2,7 +2,6 @@ package d2netpacket import ( "encoding/json" - "log" "time" "github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket/d2netpackettype" @@ -16,18 +15,18 @@ type PingPacket struct { // CreatePingPacket returns a NetPacket which declares a GenerateMapPacket // with the the current time. -func CreatePingPacket() NetPacket { +func CreatePingPacket() (NetPacket, error) { ping := PingPacket{ TS: time.Now(), } b, err := json.Marshal(ping) if err != nil { - log.Print(err) + return NetPacket{PacketType: d2netpackettype.Ping}, err } return NetPacket{ PacketType: d2netpackettype.Ping, PacketData: b, - } + }, nil } diff --git a/d2networking/d2netpacket/packet_player_cast.go b/d2networking/d2netpacket/packet_player_cast.go index 8388e71a..e0dfa3fb 100644 --- a/d2networking/d2netpacket/packet_player_cast.go +++ b/d2networking/d2netpacket/packet_player_cast.go @@ -2,7 +2,6 @@ package d2netpacket import ( "encoding/json" - "log" "github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket/d2netpackettype" ) @@ -20,7 +19,7 @@ type CastPacket struct { // CreateCastPacket returns a NetPacket which declares a CastPacket with the // given skill command. -func CreateCastPacket(entityID string, skillID int, targetX, targetY float64) NetPacket { +func CreateCastPacket(entityID string, skillID int, targetX, targetY float64) (NetPacket, error) { castPacket := CastPacket{ SourceEntityID: entityID, SkillID: skillID, @@ -31,13 +30,13 @@ func CreateCastPacket(entityID string, skillID int, targetX, targetY float64) Ne b, err := json.Marshal(castPacket) if err != nil { - log.Print(err) + return NetPacket{PacketType: d2netpackettype.CastSkill}, err } return NetPacket{ PacketType: d2netpackettype.CastSkill, PacketData: b, - } + }, nil } // UnmarshalCast unmarshals the given data to a CastPacket struct diff --git a/d2networking/d2netpacket/packet_player_connection_request.go b/d2networking/d2netpacket/packet_player_connection_request.go index aba789f5..2617141d 100644 --- a/d2networking/d2netpacket/packet_player_connection_request.go +++ b/d2networking/d2netpacket/packet_player_connection_request.go @@ -2,7 +2,6 @@ package d2netpacket import ( "encoding/json" - "log" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero" @@ -18,7 +17,7 @@ type PlayerConnectionRequestPacket struct { // CreatePlayerConnectionRequestPacket returns a NetPacket which defines a // PlayerConnectionRequestPacket with the given ID and game state. -func CreatePlayerConnectionRequestPacket(id string, playerState *d2hero.HeroState) NetPacket { +func CreatePlayerConnectionRequestPacket(id string, playerState *d2hero.HeroState) (NetPacket, error) { playerConnectionRequest := PlayerConnectionRequestPacket{ ID: id, PlayerState: playerState, @@ -26,13 +25,13 @@ func CreatePlayerConnectionRequestPacket(id string, playerState *d2hero.HeroStat b, err := json.Marshal(playerConnectionRequest) if err != nil { - log.Print(err) + return NetPacket{PacketType: d2netpackettype.PlayerConnectionRequest}, err } return NetPacket{ PacketType: d2netpackettype.PlayerConnectionRequest, PacketData: b, - } + }, nil } // UnmarshalPlayerConnectionRequest unmarshals the given data to a diff --git a/d2networking/d2netpacket/packet_player_disconnect_request.go b/d2networking/d2netpacket/packet_player_disconnect_request.go index a2c7a8f7..456d4106 100644 --- a/d2networking/d2netpacket/packet_player_disconnect_request.go +++ b/d2networking/d2netpacket/packet_player_disconnect_request.go @@ -2,7 +2,6 @@ package d2netpacket import ( "encoding/json" - "log" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero" @@ -18,20 +17,20 @@ type PlayerDisconnectRequestPacket struct { // CreatePlayerDisconnectRequestPacket returns a NetPacket which defines a // PlayerDisconnectRequestPacket with the given ID. -func CreatePlayerDisconnectRequestPacket(id string) NetPacket { +func CreatePlayerDisconnectRequestPacket(id string) (NetPacket, error) { playerDisconnectRequest := PlayerDisconnectRequestPacket{ ID: id, } b, err := json.Marshal(playerDisconnectRequest) if err != nil { - log.Print(err) + return NetPacket{PacketType: d2netpackettype.PlayerDisconnectionNotification}, err } return NetPacket{ PacketType: d2netpackettype.PlayerDisconnectionNotification, PacketData: b, - } + }, nil } // UnmarshalPlayerDisconnectionRequest unmarshals the given data to a diff --git a/d2networking/d2netpacket/packet_pong.go b/d2networking/d2netpacket/packet_pong.go index e34ed71a..7d98ac63 100644 --- a/d2networking/d2netpacket/packet_pong.go +++ b/d2networking/d2netpacket/packet_pong.go @@ -2,7 +2,6 @@ package d2netpacket import ( "encoding/json" - "log" "time" "github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket/d2netpackettype" @@ -17,7 +16,7 @@ type PongPacket struct { // CreatePongPacket returns a NetPacket which declares a PongPacket with // the current time and given ID. -func CreatePongPacket(id string) NetPacket { +func CreatePongPacket(id string) (NetPacket, error) { pong := PongPacket{ ID: id, TS: time.Now(), @@ -25,13 +24,13 @@ func CreatePongPacket(id string) NetPacket { b, err := json.Marshal(pong) if err != nil { - log.Print(err) + return NetPacket{PacketType: d2netpackettype.Pong}, err } return NetPacket{ PacketType: d2netpackettype.Pong, PacketData: b, - } + }, nil } // UnmarshalPong unmarshals the given data to a PongPacket struct diff --git a/d2networking/d2netpacket/packet_save_player.go b/d2networking/d2netpacket/packet_save_player.go index 72be8629..86fd2f24 100644 --- a/d2networking/d2netpacket/packet_save_player.go +++ b/d2networking/d2netpacket/packet_save_player.go @@ -2,7 +2,6 @@ package d2netpacket import ( "encoding/json" - "log" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity" "github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket/d2netpackettype" @@ -15,20 +14,20 @@ type SavePlayerPacket struct { } // CreateSavePlayerPacket sends a packet which instructs the server to save the Player -func CreateSavePlayerPacket(playerState *d2mapentity.Player) NetPacket { +func CreateSavePlayerPacket(playerState *d2mapentity.Player) (NetPacket, error) { savePlayerData := SavePlayerPacket{ Player: playerState, } b, err := json.Marshal(savePlayerData) if err != nil { - log.Print(err) + return NetPacket{PacketType: d2netpackettype.SavePlayer}, err } return NetPacket{ PacketType: d2netpackettype.SavePlayer, PacketData: b, - } + }, nil } // UnmarshalSavePlayer unmarshalls the given data to a SavePlayerPacket struct diff --git a/d2networking/d2netpacket/packet_server_closed.go b/d2networking/d2netpacket/packet_server_closed.go index 546bcb3a..eb7fcb19 100644 --- a/d2networking/d2netpacket/packet_server_closed.go +++ b/d2networking/d2netpacket/packet_server_closed.go @@ -2,7 +2,6 @@ package d2netpacket import ( "encoding/json" - "log" "time" "github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket/d2netpackettype" @@ -16,20 +15,20 @@ type ServerClosedPacket struct { // CreateServerClosedPacket returns a NetPacket which declares a // ServerClosedPacket with the current time. -func CreateServerClosedPacket() NetPacket { +func CreateServerClosedPacket() (NetPacket, error) { serverClosed := ServerClosedPacket{ TS: time.Now(), } b, err := json.Marshal(serverClosed) if err != nil { - log.Print(err) + return NetPacket{PacketType: d2netpackettype.ServerClosed}, err } return NetPacket{ PacketType: d2netpackettype.ServerClosed, PacketData: b, - } + }, nil } // UnmarshalServerClosed unmarshals the given data to a ServerClosedPacket struct diff --git a/d2networking/d2netpacket/packet_server_full.go b/d2networking/d2netpacket/packet_server_full.go index 21b1eda6..9e30bfa7 100644 --- a/d2networking/d2netpacket/packet_server_full.go +++ b/d2networking/d2netpacket/packet_server_full.go @@ -2,7 +2,6 @@ package d2netpacket import ( "encoding/json" - "log" "github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket/d2netpackettype" ) @@ -12,18 +11,18 @@ import ( type ServerFullPacket struct{} // CreateServerFullPacket returns a NetPacket which declares a ServerFullPacket. -func CreateServerFullPacket() NetPacket { +func CreateServerFullPacket() (NetPacket, error) { serverClosed := ServerFullPacket{} b, err := json.Marshal(serverClosed) if err != nil { - log.Print(err) + return NetPacket{PacketType: d2netpackettype.ServerFull}, err } return NetPacket{ PacketType: d2netpackettype.ServerFull, PacketData: b, - } + }, nil } // UnmarshalServerFull unmarshalls the given data to a ServerFullPacket struct diff --git a/d2networking/d2netpacket/packet_update_server_info.go b/d2networking/d2netpacket/packet_update_server_info.go index 8043a1da..77c53e4a 100644 --- a/d2networking/d2netpacket/packet_update_server_info.go +++ b/d2networking/d2netpacket/packet_update_server_info.go @@ -2,7 +2,6 @@ package d2netpacket import ( "encoding/json" - "log" "github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket/d2netpackettype" ) @@ -16,7 +15,7 @@ type UpdateServerInfoPacket struct { // CreateUpdateServerInfoPacket returns a NetPacket which declares an // UpdateServerInfoPacket with the given player ID and map seed. -func CreateUpdateServerInfoPacket(seed int64, playerID string) NetPacket { +func CreateUpdateServerInfoPacket(seed int64, playerID string) (NetPacket, error) { updateServerInfo := UpdateServerInfoPacket{ Seed: seed, PlayerID: playerID, @@ -24,13 +23,13 @@ func CreateUpdateServerInfoPacket(seed int64, playerID string) NetPacket { b, err := json.Marshal(updateServerInfo) if err != nil { - log.Print(err) + return NetPacket{PacketType: d2netpackettype.UpdateServerInfo}, err } return NetPacket{ PacketType: d2netpackettype.UpdateServerInfo, PacketData: b, - } + }, nil } // UnmarshalUpdateServerInfo unmarshals the data to a UpdateServerInfoPacket struct diff --git a/d2networking/d2server/d2udpclientconnection/udp_client_connection.go b/d2networking/d2server/d2udpclientconnection/udp_client_connection.go index 8acf0717..6dfa456f 100644 --- a/d2networking/d2server/d2udpclientconnection/udp_client_connection.go +++ b/d2networking/d2server/d2udpclientconnection/udp_client_connection.go @@ -6,7 +6,6 @@ import ( "compress/gzip" "encoding/json" "fmt" - "log" "net" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero" @@ -14,8 +13,12 @@ import ( "github.com/OpenDiablo2/OpenDiablo2/d2networking/d2client/d2clientconnectiontype" "github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket" + + "github.com/OpenDiablo2/OpenDiablo2/d2common/d2util" ) +const logPrefix = "UDP Connection" + // UDPClientConnection is the implementation of the // d2server.ClientConnection interface to represent remote client from the // server perspective. @@ -24,17 +27,23 @@ type UDPClientConnection struct { address *net.UDPAddr // IP address of the associated RemoteClientConnection udpConnection *net.UDPConn // Server's UDP Connection playerState *d2hero.HeroState // Client's game state + + *d2util.Logger } // CreateUDPClientConnection constructs a new UDPClientConnection and // returns a pointer to it. -func CreateUDPClientConnection(udpConnection *net.UDPConn, id string, address *net.UDPAddr) *UDPClientConnection { +func CreateUDPClientConnection(udpConnection *net.UDPConn, id string, l d2util.LogLevel, address *net.UDPAddr) *UDPClientConnection { result := &UDPClientConnection{ id: id, address: address, udpConnection: udpConnection, } + result.Logger = d2util.NewLogger() + result.Logger.SetPrefix(logPrefix) + result.Logger.SetLevel(l) + return result } @@ -63,7 +72,7 @@ func (u *UDPClientConnection) SendPacketToClient(packet d2netpacket.NetPacket) e writer, err := gzip.NewWriterLevel(&buff, gzip.BestCompression) if err != nil { - log.Print(err) + u.Error(err.Error()) } if written, writeErr := writer.Write(data); writeErr != nil { diff --git a/d2networking/d2server/game_server.go b/d2networking/d2server/game_server.go index fbec2c30..0d4bec42 100644 --- a/d2networking/d2server/game_server.go +++ b/d2networking/d2server/game_server.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "errors" - "fmt" "net" "sync" "time" @@ -112,7 +111,7 @@ func NewGameServer(asset *d2asset.AssetManager, gameServer.scriptEngine.AddFunction("getMapEngines", func(call otto.FunctionCall) otto.Value { val, err := gameServer.scriptEngine.ToValue(gameServer.mapEngines) if err != nil { - fmt.Print(err.Error()) + gameServer.Error(err.Error()) } return val }) @@ -174,7 +173,12 @@ func (g *GameServer) packetManager() { case <-g.ctx.Done(): return case p := <-g.packetManagerChan: - switch d2netpacket.InspectPacketType(p) { + ipt, err := d2netpacket.InspectPacketType(p) + if err != nil { + g.Errorf("InspectPacketType: %v", err) + } + + switch ipt { case d2netpackettype.PlayerConnectionRequest: player, err := d2netpacket.UnmarshalNetPacket(p) if err != nil { @@ -256,10 +260,20 @@ func (g *GameServer) handleConnection(conn net.Conn) { if err := g.registerConnection(packet.PacketData, conn); err != nil { switch err { case errServerFull: // Server is currently full and not accepting new connections. - _, errServerFullPacket := conn.Write(d2netpacket.MarshalPacket(d2netpacket.CreateServerFullPacket())) - g.Error(fmt.Sprintln(errServerFullPacket)) + sf, serverFullErr := d2netpacket.CreateServerFullPacket() + if serverFullErr != nil { + g.Errorf("ServerFullPacket: %v", serverFullErr) + } + + msf, marshalServerFullErr := d2netpacket.MarshalPacket(sf) + if marshalServerFullErr != nil { + g.Errorf("MarshalPacket: %v", marshalServerFullErr) + } + + _, errServerFullPacket := conn.Write(msf) + g.Warningf("%v", errServerFullPacket) case errPlayerAlreadyExists: // Player is already registered and did not disconnection correctly. - g.Error(fmt.Sprintln(err)) + g.Errorf("%v", err) } return @@ -347,12 +361,22 @@ func (g *GameServer) OnClientConnected(client ClientConnection) { } func (g *GameServer) handleClientConnection(client ClientConnection, x, y float64) { - err := client.SendPacketToClient(d2netpacket.CreateUpdateServerInfoPacket(g.seed, client.GetUniqueID())) + usi, err := d2netpacket.CreateUpdateServerInfoPacket(g.seed, client.GetUniqueID()) + if err != nil { + g.Errorf("UpdateServerInfoPacket: %v", err) + } + + err = client.SendPacketToClient(usi) if err != nil { g.Errorf("GameServer: error sending UpdateServerInfoPacket to client %s: %s", client.GetUniqueID(), err) } - err = client.SendPacketToClient(d2netpacket.CreateGenerateMapPacket(d2enum.RegionAct1Town)) + gmp, err := d2netpacket.CreateGenerateMapPacket(d2enum.RegionAct1Town) + if err != nil { + g.Errorf("GenerateMapPacket: %v", err) + } + + err = client.SendPacketToClient(gmp) if err != nil { g.Errorf("GameServer: error sending GenerateMapPacket to client %s: %s", client.GetUniqueID(), err) } @@ -365,7 +389,7 @@ func (g *GameServer) handleClientConnection(client ClientConnection, x, y float6 d2hero.HydrateSkills(playerState.Skills, g.asset) - createPlayerPacket := d2netpacket.CreateAddPlayerPacket( + createPlayerPacket, err := d2netpacket.CreateAddPlayerPacket( client.GetUniqueID(), playerState.HeroName, playerX, @@ -378,6 +402,9 @@ func (g *GameServer) handleClientConnection(client ClientConnection, x, y float6 playerState.RightSkill, playerState.Gold, ) + if err != nil { + g.Errorf("AddPlayerPacket: %v", err) + } for _, connection := range g.connections { err := connection.SendPacketToClient(createPlayerPacket) @@ -392,22 +419,26 @@ func (g *GameServer) handleClientConnection(client ClientConnection, x, y float6 conPlayerState := connection.GetPlayerState() playerX := int(conPlayerState.X*subtilesPerTile) + middleOfTileOffset playerY := int(conPlayerState.Y*subtilesPerTile) + middleOfTileOffset - err = client.SendPacketToClient( - d2netpacket.CreateAddPlayerPacket( - connection.GetUniqueID(), - conPlayerState.HeroName, - playerX, - playerY, - conPlayerState.HeroType, - conPlayerState.Stats, - conPlayerState.Skills, - conPlayerState.Equipment, - conPlayerState.LeftSkill, - conPlayerState.RightSkill, - conPlayerState.Gold, - ), + app, err := d2netpacket.CreateAddPlayerPacket( + connection.GetUniqueID(), + conPlayerState.HeroName, + playerX, + playerY, + conPlayerState.HeroType, + conPlayerState.Stats, + conPlayerState.Skills, + conPlayerState.Equipment, + conPlayerState.LeftSkill, + conPlayerState.RightSkill, + conPlayerState.Gold, ) + if err != nil { + g.Errorf("AddPlayerPacket: %v", err) + } + + err = client.SendPacketToClient(app) + if err != nil { g.Errorf("GameServer: error sending CreateAddPlayerPacket to client %s: %s", connection.GetUniqueID(), err) } From 569608295caa1cf237fe83b6fd874bd38a53f76d Mon Sep 17 00:00:00 2001 From: "M. Sz" Date: Mon, 23 Nov 2020 18:07:51 +0100 Subject: [PATCH 2/4] fixed build errors --- d2game/d2gamescreen/game.go | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/d2game/d2gamescreen/game.go b/d2game/d2gamescreen/game.go index 77e084c3..7e0dd522 100644 --- a/d2game/d2gamescreen/game.go +++ b/d2game/d2gamescreen/game.go @@ -326,8 +326,13 @@ func (v *Game) OnPlayerMove(targetX, targetY float64) { worldPosition := v.localPlayer.Position.World() playerID, worldX, worldY := v.gameClient.PlayerID, worldPosition.X(), worldPosition.Y() - createMovePlayerPacket := d2netpacket.CreateMovePlayerPacket(playerID, worldX, worldY, targetX, targetY) - err := v.gameClient.SendPacketToServer(createMovePlayerPacket) + + createMovePlayerPacket, err := d2netpacket.CreateMovePlayerPacket(playerID, worldX, worldY, targetX, targetY) + if err != nil { + v.Errorf("MovePlayerPacket: %v", err) + } + + err = v.gameClient.SendPacketToServer(createMovePlayerPacket) if err != nil { v.Errorf(moveErrStr, v.gameClient.PlayerID, targetX, targetY) @@ -337,7 +342,13 @@ func (v *Game) OnPlayerMove(targetX, targetY float64) { // OnPlayerSave instructs the server to save our player data func (v *Game) OnPlayerSave() error { playerState := v.gameClient.Players[v.gameClient.PlayerID] - err := v.gameClient.SendPacketToServer(d2netpacket.CreateSavePlayerPacket(playerState)) + + sp, err := d2netpacket.CreateSavePlayerPacket(playerState) + if err != nil { + return fmt.Errorf("SavePlayerPacket: %v", err) + } + + err = v.gameClient.SendPacketToServer(sp) if err != nil { return err @@ -348,7 +359,12 @@ func (v *Game) OnPlayerSave() error { // OnPlayerCast sends the casting skill action to the server func (v *Game) OnPlayerCast(skillID int, targetX, targetY float64) { - err := v.gameClient.SendPacketToServer(d2netpacket.CreateCastPacket(v.gameClient.PlayerID, skillID, targetX, targetY)) + cp, err := d2netpacket.CreateCastPacket(v.gameClient.PlayerID, skillID, targetX, targetY) + if err != nil { + v.Errorf("CastPacket: %v", err) + } + + err = v.gameClient.SendPacketToServer(cp) if err != nil { v.Errorf(castErrStr, v.gameClient.PlayerID, skillID, targetX, targetY) } @@ -367,9 +383,12 @@ func (v *Game) debugSpawnItemAtPlayer(codes ...string) { } func (v *Game) debugSpawnItemAtLocation(x, y int, codes ...string) { - packet := d2netpacket.CreateSpawnItemPacket(x, y, codes...) + packet, err := d2netpacket.CreateSpawnItemPacket(x, y, codes...) + if err != nil { + v.Errorf("SpawnItemPacket: %v", err) + } - err := v.gameClient.SendPacketToServer(packet) + err = v.gameClient.SendPacketToServer(packet) if err != nil { v.Errorf(spawnItemErrStr, x, y, codes) } From 5e0b28c09e7a7635a2e86b079d3c8c2cd31ff9be Mon Sep 17 00:00:00 2001 From: "M. Sz" Date: Mon, 23 Nov 2020 18:16:56 +0100 Subject: [PATCH 3/4] "fixed" lint error --- .../d2client/d2remoteclient/remote_client_connection.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/d2networking/d2client/d2remoteclient/remote_client_connection.go b/d2networking/d2client/d2remoteclient/remote_client_connection.go index 84875a45..9f47744e 100644 --- a/d2networking/d2client/d2remoteclient/remote_client_connection.go +++ b/d2networking/d2client/d2remoteclient/remote_client_connection.go @@ -182,7 +182,7 @@ func (r *RemoteClientConnection) bytesToJSON(buffer []byte) (string, d2netpacket // decodeToPacket unmarshals the JSON string into the correct struct // and returns a NetPacket declaring that struct. -// nolint:gocyclo // switch statement on packet type makes sense, no need to change +// nolint:gocyclo,funlen // switch statement on packet type makes sense, no need to change func (r *RemoteClientConnection) decodeToPacket( t d2netpackettype.NetPacketType, data string) (d2netpacket.NetPacket, error) { From 33bc9fe434f36edb0459939c057db2bb28c2bbab Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 25 Nov 2020 08:45:30 +0100 Subject: [PATCH 4/4] locale strings for character select & hero stat panel (#948) * character select screen's hero descriptions & hero stat panel * cinematics names * buttons on character select screen and "resistances" labels on hero stats panel Co-authored-by: M. Sz --- d2common/d2util/stringutils.go | 5 +++ d2core/d2asset/asset_manager.go | 25 +++++++++++ d2game/d2gamescreen/character_select.go | 15 ++++--- d2game/d2gamescreen/cinematics.go | 25 ++++------- d2game/d2player/hero_stats_panel.go | 59 ++++++++++++++----------- 5 files changed, 78 insertions(+), 51 deletions(-) diff --git a/d2common/d2util/stringutils.go b/d2common/d2util/stringutils.go index c9c859cb..24f268bd 100644 --- a/d2common/d2util/stringutils.go +++ b/d2common/d2util/stringutils.go @@ -135,6 +135,11 @@ func SplitIntoLinesWithMaxWidth(fullSentence string, maxChars int) []string { return lines } +// SplitIntoLinesWithMaxWidthOneLine does the same as SplitIntoLinesWithMaxWidth but return string with newline char +func SplitIntoLinesWithMaxWidthOneLine(s string, l int) string { + return strings.Join(SplitIntoLinesWithMaxWidth(s, l), "\n") +} + func splitCjkIntoChunks(str string, chars int) []string { chunks := make([]string, chars/len(str)) i, count := 0, 0 diff --git a/d2core/d2asset/asset_manager.go b/d2core/d2asset/asset_manager.go index d710b115..5a5acdec 100644 --- a/d2core/d2asset/asset_manager.go +++ b/d2core/d2asset/asset_manager.go @@ -291,6 +291,31 @@ func (am *AssetManager) TranslateString(key string) string { return key } +// TranslateHeroClass translates her class given to game locale +func (am *AssetManager) TranslateHeroClass(h d2enum.Hero) string { + switch h { + case d2enum.HeroBarbarian: + return am.TranslateString("Barbarian") + case d2enum.HeroNecromancer: + return am.TranslateString("Necromancer") + case d2enum.HeroPaladin: + return am.TranslateString("Paladin") + case d2enum.HeroAssassin: + return am.TranslateString("Assassin") + case d2enum.HeroSorceress: + return am.TranslateString("Sorceress") + case d2enum.HeroAmazon: + return am.TranslateString("Amazon") + case d2enum.HeroDruid: + return am.TranslateString("Druid") + default: + am.Error("Unknown Hero Class") + } + + // should not be reached + return "---" +} + // LoadPaletteTransform loads a palette transform file func (am *AssetManager) LoadPaletteTransform(path string) (*d2pl2.PL2, error) { if pl2, found := am.transforms.Retrieve(path); found { diff --git a/d2game/d2gamescreen/character_select.go b/d2game/d2gamescreen/character_select.go index bbbc8015..6bd355f8 100644 --- a/d2game/d2gamescreen/character_select.go +++ b/d2game/d2gamescreen/character_select.go @@ -292,17 +292,17 @@ func rgbaColor(rgba uint32) color.RGBA { } func (v *CharacterSelect) createButtons(loading d2screen.LoadingState) { - v.newCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall, "CREATE NEW\nCHARACTER") - + v.newCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall, d2util.SplitIntoLinesWithMaxWidthOneLine(v.asset.TranslateString("#831"), 13)) v.newCharButton.SetPosition(newCharBtnX, newCharBtnY) v.newCharButton.OnActivated(func() { v.onNewCharButtonClicked() }) - v.convertCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall, "CONVERT TO\nEXPANSION") - + v.convertCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall, + d2util.SplitIntoLinesWithMaxWidthOneLine(v.asset.TranslateString("#825"), 13)) v.convertCharButton.SetPosition(convertCharBtnX, convertCharBtnY) v.convertCharButton.SetEnabled(false) - v.deleteCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall, "DELETE\nCHARACTER") + v.deleteCharButton = v.uiManager.NewButton(d2ui.ButtonTypeTall, + d2util.SplitIntoLinesWithMaxWidthOneLine(v.asset.TranslateString("#832"), 13)) v.deleteCharButton.OnActivated(func() { v.onDeleteCharButtonClicked() }) v.deleteCharButton.SetPosition(deleteCharBtnX, deleteCharBtnY) @@ -333,7 +333,7 @@ func (v *CharacterSelect) onScrollUpdate() { } func (v *CharacterSelect) updateCharacterBoxes() { - expText := "EXPANSION CHARACTER" + expText := v.asset.TranslateString("#803") for i := 0; i < 8; i++ { idx := i + (v.charScrollbar.GetCurrentOffset() * 2) @@ -348,7 +348,8 @@ func (v *CharacterSelect) updateCharacterBoxes() { } heroName := v.gameStates[idx].HeroName - heroInfo := "Level " + strconv.FormatInt(int64(v.gameStates[idx].Stats.Level), 10) + " " + v.gameStates[idx].HeroType.String() + heroInfo := v.asset.TranslateString("level") + " " + strconv.FormatInt(int64(v.gameStates[idx].Stats.Level), 10) + + " " + v.asset.TranslateHeroClass(v.gameStates[idx].HeroType) v.characterNameLabel[i].SetText(d2ui.ColorTokenize(heroName, d2ui.ColorTokenGold)) v.characterStatsLabel[i].SetText(d2ui.ColorTokenize(heroInfo, d2ui.ColorTokenWhite)) diff --git a/d2game/d2gamescreen/cinematics.go b/d2game/d2gamescreen/cinematics.go index 2a7a07b7..718c0efb 100644 --- a/d2game/d2gamescreen/cinematics.go +++ b/d2game/d2gamescreen/cinematics.go @@ -102,44 +102,35 @@ func (v *Cinematics) OnLoad(_ d2screen.LoadingState) { } func (v *Cinematics) createButtons() { - /*CINEMATICS NAMES: - Act 1: The Sister's Lament - Act 2: Dessert Journay - Act 3: Mephisto's Jungle - Act 4: Enter Hell - Act 5: Search For Ball - end Credit Classic: Terror's End - end Credit Expansion: Destruction's End - */ - v.cinematicsExitBtn = v.uiManager.NewButton(d2ui.ButtonTypeMedium, "CANCEL") + v.cinematicsExitBtn = v.uiManager.NewButton(d2ui.ButtonTypeMedium, v.asset.TranslateString("cancel")) v.cinematicsExitBtn.SetPosition(cinematicsExitBtnX, cinematicsExitBtnY) v.cinematicsExitBtn.OnActivated(func() { v.onCinematicsExitBtnClicked() }) - v.a1Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, "THE SISTER'S LAMENT") + v.a1Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateString("act1X")) v.a1Btn.SetPosition(a1BtnX, a1BtnY) v.a1Btn.OnActivated(func() { v.onA1BtnClicked() }) - v.a2Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, "DESSERT JOURNAY") + v.a2Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateString("act2X")) v.a2Btn.SetPosition(a2BtnX, a2BtnY) v.a2Btn.OnActivated(func() { v.onA2BtnClicked() }) - v.a3Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, "MEPHISTO'S JUNGLE") + v.a3Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateString("act3X")) v.a3Btn.SetPosition(a3BtnX, a3BtnY) v.a3Btn.OnActivated(func() { v.onA3BtnClicked() }) - v.a4Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, "ENTER HELL") + v.a4Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateString("act4X")) v.a4Btn.SetPosition(a4BtnX, a4BtnY) v.a4Btn.OnActivated(func() { v.onA4BtnClicked() }) - v.endCreditClassBtn = v.uiManager.NewButton(d2ui.ButtonTypeWide, "TERROR'S END") + v.endCreditClassBtn = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateString("strepilogueX")) v.endCreditClassBtn.SetPosition(endCreditClassBtnX, endCreditClassBtnY) v.endCreditClassBtn.OnActivated(func() { v.onEndCreditClassBtnClicked() }) - v.a5Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, "SEARCH FOR BAAL") + v.a5Btn = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateString("act5X")) v.a5Btn.SetPosition(a5BtnX, a5BtnY) v.a5Btn.OnActivated(func() { v.onA5BtnClicked() }) - v.endCreditExpBtn = v.uiManager.NewButton(d2ui.ButtonTypeWide, "DESTRUCTION'S END") + v.endCreditExpBtn = v.uiManager.NewButton(d2ui.ButtonTypeWide, v.asset.TranslateString("strlastcinematic")) v.endCreditExpBtn.SetPosition(endCreditExpBtnX, endCreditExpBtnY) v.endCreditExpBtn.OnActivated(func() { v.onEndCreditExpBtnClicked() }) } diff --git a/d2game/d2player/hero_stats_panel.go b/d2game/d2player/hero_stats_panel.go index 922d345d..d1814a65 100644 --- a/d2game/d2player/hero_stats_panel.go +++ b/d2game/d2player/hero_stats_panel.go @@ -2,6 +2,7 @@ package d2player import ( "strconv" + "strings" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface" @@ -27,14 +28,14 @@ const ( labelLevelX, labelLevelY = 110, 100 labelHeroNameX, labelHeroNameY = 165, 72 - labelHeroClassX, labelHeroClassY = 330, 72 + labelHeroClassX, labelHeroClassY = 330, 74 labelExperienceX, labelExperienceY = 200, 100 labelNextLevelX, labelNextLevelY = 330, 100 labelStrengthX, labelStrengthY = 100, 150 labelDexterityX, labelDexterityY = 100, 213 - labelVitalityX, labelVitalityY = 100, 300 + labelVitalityX, labelVitalityY = 95, 300 labelEnergyX, labelEnergyY = 100, 360 labelDefenseX, labelDefenseY = 280, 260 @@ -42,14 +43,14 @@ const ( labelLifeX, labelLifeY = 280, 322 labelManaX, labelManaY = 280, 360 - labelResFireLine1X, labelResFireLine1Y = 310, 395 - labelResFireLine2X, labelResFireLine2Y = 310, 402 - labelResColdLine1X, labelResColdLine1Y = 310, 445 + labelResFireLine1X, labelResFireLine1Y = 310, 396 + labelResFireLine2X, labelResFireLine2Y = 310, 403 + labelResColdLine1X, labelResColdLine1Y = 310, 444 labelResColdLine2X, labelResColdLine2Y = 310, 452 labelResLightLine1X, labelResLightLine1Y = 310, 420 - labelResLightLine2X, labelResLightLine2Y = 310, 427 + labelResLightLine2X, labelResLightLine2Y = 310, 428 labelResPoisLine1X, labelResPoisLine1Y = 310, 468 - labelResPoisLine2X, labelResPoisLine2Y = 310, 477 + labelResPoisLine2X, labelResPoisLine2Y = 310, 476 ) const ( @@ -241,6 +242,10 @@ func (s *HeroStatsPanel) renderStaticPanelFrames(target d2interface.Surface) { func (s *HeroStatsPanel) renderStaticLabels(target d2interface.Surface) { var label *d2ui.Label + fr := strings.Split(s.asset.TranslateString("strchrfir"), "\n") + lr := strings.Split(s.asset.TranslateString("strchrlit"), "\n") + cr := strings.Split(s.asset.TranslateString("strchrcol"), "\n") + pr := strings.Split(s.asset.TranslateString("strchrpos"), "\n") // all static labels are not stored since we use them only once to generate the image cache var staticLabelConfigs = []struct { x, y int @@ -249,32 +254,32 @@ func (s *HeroStatsPanel) renderStaticLabels(target d2interface.Surface) { centerAlign bool }{ {labelHeroNameX, labelHeroNameY, s.heroName, d2resource.Font16, true}, - {labelHeroClassX, labelHeroClassY, s.heroClass.String(), d2resource.Font16, true}, + {labelHeroClassX, labelHeroClassY, s.asset.TranslateHeroClass(s.heroClass), d2resource.Font16, true}, - {labelLevelX, labelLevelY, "Level", d2resource.Font6, true}, - {labelExperienceX, labelExperienceY, "Experience", d2resource.Font6, true}, - {labelNextLevelX, labelNextLevelY, "Next Level", d2resource.Font6, true}, - {labelStrengthX, labelStrengthY, "Strength", d2resource.Font6, false}, - {labelDexterityX, labelDexterityY, "Dexterity", d2resource.Font6, false}, - {labelVitalityX, labelVitalityY, "Vitality", d2resource.Font6, false}, - {labelEnergyX, labelEnergyY, "Energy", d2resource.Font6, false}, - {labelDefenseX, labelDefenseY, "Defense", d2resource.Font6, false}, - {labelStaminaX, labelStaminaY, "Stamina", d2resource.Font6, true}, - {labelLifeX, labelLifeY, "Life", d2resource.Font6, true}, - {labelManaX, labelManaY, "Mana", d2resource.Font6, true}, + {labelLevelX, labelLevelY, s.asset.TranslateString("strchrlvl"), d2resource.Font6, true}, + {labelExperienceX, labelExperienceY, s.asset.TranslateString("strchrexp"), d2resource.Font6, true}, + {labelNextLevelX, labelNextLevelY, s.asset.TranslateString("strchrnxtlvl"), d2resource.Font6, true}, + {labelStrengthX, labelStrengthY, s.asset.TranslateString("strchrstr"), d2resource.Font6, false}, + {labelDexterityX, labelDexterityY, s.asset.TranslateString("strchrdex"), d2resource.Font6, false}, + {labelVitalityX, labelVitalityY, s.asset.TranslateString("strchrvit"), d2resource.Font6, false}, + {labelEnergyX, labelEnergyY, s.asset.TranslateString("strchreng"), d2resource.Font6, false}, + {labelDefenseX, labelDefenseY, s.asset.TranslateString("strchrdef"), d2resource.Font6, false}, + {labelStaminaX, labelStaminaY, s.asset.TranslateString("strchrstm"), d2resource.Font6, true}, + {labelLifeX, labelLifeY, s.asset.TranslateString("strchrlif"), d2resource.Font6, true}, + {labelManaX, labelManaY, s.asset.TranslateString("strchrman"), d2resource.Font6, true}, // can't use "Fire\nResistance" because line spacing is too big and breaks the layout - {labelResFireLine1X, labelResFireLine1Y, "Fire", d2resource.Font6, true}, - {labelResFireLine2X, labelResFireLine2Y, "Resistance", d2resource.Font6, true}, + {labelResFireLine1X, labelResFireLine1Y, fr[0], d2resource.Font6, true}, + {labelResFireLine2X, labelResFireLine2Y, fr[len(fr)-1], d2resource.Font6, true}, - {labelResColdLine1X, labelResColdLine1Y, "Cold", d2resource.Font6, true}, - {labelResColdLine2X, labelResColdLine2Y, "Resistance", d2resource.Font6, true}, + {labelResColdLine1X, labelResColdLine1Y, cr[0], d2resource.Font6, true}, + {labelResColdLine2X, labelResColdLine2Y, cr[len(cr)-1], d2resource.Font6, true}, - {labelResLightLine1X, labelResLightLine1Y, "Lightning", d2resource.Font6, true}, - {labelResLightLine2X, labelResLightLine2Y, "Resistance", d2resource.Font6, true}, + {labelResLightLine1X, labelResLightLine1Y, lr[0], d2resource.Font6, true}, + {labelResLightLine2X, labelResLightLine2Y, lr[len(lr)-1], d2resource.Font6, true}, - {labelResPoisLine1X, labelResPoisLine1Y, "Poison", d2resource.Font6, true}, - {labelResPoisLine2X, labelResPoisLine2Y, "Resistance", d2resource.Font6, true}, + {labelResPoisLine1X, labelResPoisLine1Y, pr[0], d2resource.Font6, true}, + {labelResPoisLine2X, labelResPoisLine2Y, pr[len(pr)-1], d2resource.Font6, true}, } for _, cfg := range staticLabelConfigs {