Skip to content

Commit

Permalink
Merge pull request #15 from hexis-revival/logging-refactor
Browse files Browse the repository at this point in the history
Refactor logging of structs
  • Loading branch information
Lekuruu authored Oct 10, 2024
2 parents 43d3e58 + 3c2d8a5 commit 092a116
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 120 deletions.
2 changes: 1 addition & 1 deletion common/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (ec *ErrorCollection) HasErrors() bool {
}

func (ec *ErrorCollection) String() string {
return fmt.Sprintf("ErrorCollection{%d errors}", len(ec.errors))
return fmt.Sprintf("ErrorCollection{errors: %v}", len(ec.errors))
}

func NewErrorCollection() *ErrorCollection {
Expand Down
73 changes: 73 additions & 0 deletions common/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"fmt"
"log"
"os"
"reflect"
"strings"
"time"
"unicode"
)
Expand Down Expand Up @@ -98,6 +100,8 @@ func concatMessage(msg ...any) string {
return log
}

// FormatBytes returns a string representation of a byte slice
// similar to how python handles byte strings
func FormatBytes(data []byte) string {
result := ""
for _, b := range data {
Expand All @@ -112,6 +116,75 @@ func FormatBytes(data []byte) string {
return result
}

// FormatStruct returns a string representation of a struct
func FormatStruct(s interface{}) string {
v := reflect.ValueOf(s)
t := v.Type()

// Check if the value is a pointer and dereference it
if t.Kind() == reflect.Ptr {
v = v.Elem()
t = v.Type()
}

// Ensure we're dealing with a struct
if t.Kind() != reflect.Struct {
return fmt.Sprintf("%v", s)
}

var sb strings.Builder
sb.WriteString(t.Name() + "{")

for i := 0; i < v.NumField(); i++ {
field := t.Field(i)
value := v.Field(i)

// Skip unexported fields
if !field.IsExported() {
continue
}

// Append field name and formatted value
sb.WriteString(fmt.Sprintf("%s: %s", field.Name, FormatValue(value)))

if i < v.NumField()-1 {
sb.WriteString(", ")
}
}

sb.WriteString("}")
return sb.String()
}

// FormatValue handles different types and returns the formatted string
func FormatValue(v reflect.Value) string {
defer recover()
switch v.Kind() {
case reflect.String:
return fmt.Sprintf("\"%s\"", v.String())
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return fmt.Sprintf("%d", v.Uint())
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return fmt.Sprintf("%d", v.Int())
case reflect.Float32, reflect.Float64:
return fmt.Sprintf("%f", v.Float())
case reflect.Bool:
return fmt.Sprintf("%t", v.Bool())
case reflect.Slice:
if v.Type().Elem().Kind() == reflect.Uint8 {
return fmt.Sprintf("%v", v.Bytes())
}
return fmt.Sprintf("%v", v.Interface())
case reflect.Struct:
if v.Type() == reflect.TypeOf(time.Time{}) {
return v.Interface().(time.Time).Format(time.RFC3339)
}
return FormatStruct(v.Interface())
default:
return fmt.Sprintf("%v", v.Interface())
}
}

func (c *Logger) Info(msg ...any) {
if c.level > INFO {
return
Expand Down
10 changes: 2 additions & 8 deletions common/replays.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,7 @@ type ReplayHeader struct {
}

func (header *ReplayHeader) String() string {
return fmt.Sprintf(
"ReplayHeader{Mode %d, ReplayVersion: %d, BeatmapChecksum: %s, PlayerName: %s, ScoreChecksum: %s, Count300: %d, Count100: %d, Count50: %d, CountGeki: %d, CountGood: %d, CountMiss: %d, TotalScore: %f, MaxCombo: %d, FullCombo: %t, Time: %s}",
header.Mode, header.ReplayVersion, header.BeatmapChecksum, header.PlayerName, header.ScoreChecksum, header.Count300, header.Count100, header.Count50, header.CountGeki, header.CountGood, header.CountMiss, header.TotalScore, header.MaxCombo, header.FullCombo, header.Time,
)
return FormatStruct(header)
}

func (header *ReplayHeader) Serialize(stream *IOStream) {
Expand Down Expand Up @@ -143,10 +140,7 @@ type ReplayFrame struct {
}

func (frame *ReplayFrame) String() string {
return fmt.Sprintf(
"ReplayFrame{Time: %d, MouseX: %f, MouseY: %f, ButtonState: %d}",
frame.Time, frame.MouseX, frame.MouseY, frame.ButtonState,
)
return FormatStruct(frame)
}

func (frame *ReplayFrame) Serialize(stream *IOStream) {
Expand Down
41 changes: 41 additions & 0 deletions common/replays_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package common

import (
"encoding/binary"
"io"
"os"
"testing"
)

func TestReplayParsing(t *testing.T) {
file, err := os.Open("./replays_test.hxrp")
if err != nil {
t.Error(err)
return
}

replayData, err := io.ReadAll(file)
if err != nil {
t.Error(err)
return
}

stream := NewIOStream(replayData, binary.BigEndian)
replay, err := ReadFullReplay(stream)
if err != nil {
t.Error(err)
return
}

if replay.Header == nil {
t.Error("failed to read replay header")
}

if len(replay.Frames) == 0 {
t.Error("failed to read replay frames")
}

t.Cleanup(func() {
file.Close()
})
}
Binary file added common/replays_test.hxrp
Binary file not shown.
3 changes: 2 additions & 1 deletion common/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"net/http"
"os"
"strconv"

"github.com/pkg/errors"
)
Expand Down Expand Up @@ -81,7 +82,7 @@ func (storage *FileStorage) GetAvatar(userId int) ([]byte, error) {
}

func (storage *FileStorage) SaveAvatar(userId int, data []byte) error {
return storage.Save(string(userId), "avatars", data)
return storage.Save(strconv.Itoa(userId), "avatars", data)
}

func (storage *FileStorage) DefaultAvatar() ([]byte, error) {
Expand Down
78 changes: 10 additions & 68 deletions hnet/objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"crypto/md5"
"encoding/hex"
"fmt"
"strconv"
"strings"

"github.com/hexis-revival/hexagon/common"
Expand All @@ -22,12 +21,7 @@ type LoginRequest struct {
}

func (request LoginRequest) String() string {
return fmt.Sprintf(
"LoginRequest{Username: %s, Password: %s, %s}",
request.Username,
request.Password,
request.Client.String(),
)
return common.FormatStruct(request)
}

type ClientInfo struct {
Expand All @@ -40,15 +34,7 @@ type ClientInfo struct {
}

func (info ClientInfo) String() string {
return fmt.Sprintf(
"Client{Version: %s, ExecutableHash: %s, Adapters: %v, AdaptersHash: %s, UninstallId: %s, DiskSignature: %s}",
info.Version.String(),
info.ExecutableHash,
info.Adapters,
info.AdaptersHash,
info.UninstallId,
info.DiskSignature,
)
return common.FormatStruct(info)
}

func (info ClientInfo) IsWine() bool {
Expand Down Expand Up @@ -113,17 +99,7 @@ func (status Status) HasBeatmapInfo() bool {
}

func (status Status) String() string {
var beatmapString string = "nil"
if status.Beatmap != nil {
beatmapString = status.Beatmap.String()
}

return fmt.Sprintf(
"Status{UserId: %s, Action: %s, Beatmap: %s}",
strconv.Itoa(int(status.UserId)),
strconv.Itoa(int(status.Action)),
beatmapString,
)
return common.FormatStruct(status)
}

func NewStatus() *Status {
Expand All @@ -143,14 +119,7 @@ type BeatmapInfo struct {
}

func (beatmap BeatmapInfo) String() string {
return fmt.Sprintf(
"BeatmapInfo{Checksum: %s, Id: %d, Artist: %s, Title: %s, Version: %s}",
beatmap.Checksum,
beatmap.Id,
beatmap.Artist,
beatmap.Title,
beatmap.Version,
)
return common.FormatStruct(beatmap)
}

type LoginResponse struct {
Expand All @@ -160,12 +129,7 @@ type LoginResponse struct {
}

func (response LoginResponse) String() string {
return fmt.Sprintf(
"LoginResponse{Username: %s, Password: %s, UserId: %d}",
response.Username,
response.Password,
response.UserId,
)
return common.FormatStruct(response)
}

type UserInfo struct {
Expand All @@ -175,11 +139,7 @@ type UserInfo struct {
}

func (info UserInfo) String() string {
return fmt.Sprintf(
"UserInfo{UserId: %d. Username: %s}",
info.Id,
info.Name,
)
return common.FormatStruct(info)
}

func NewUserInfo() *UserInfo {
Expand All @@ -200,16 +160,7 @@ type UserStats struct {
}

func (stats UserStats) String() string {
return fmt.Sprintf(
"UserStats{UserId: %d, Rank: %d, RankedScore: %d, TotalScore: %d, Accuracy: %f, Plays: %d, %s}",
stats.UserId,
stats.Rank,
stats.RankedScore,
stats.TotalScore,
stats.Accuracy*100,
stats.Plays,
stats.Status.String(),
)
return common.FormatStruct(stats)
}

func NewUserStats() *UserStats {
Expand All @@ -228,10 +179,7 @@ type StatsRequest struct {
}

func (request StatsRequest) String() string {
return fmt.Sprintf(
"StatsRequest{UserIds: %v}",
request.UserIds,
)
return common.FormatStruct(request)
}

func NewStatsRequest() *StatsRequest {
Expand All @@ -245,10 +193,7 @@ type FriendsList struct {
}

func (friends FriendsList) String() string {
return fmt.Sprintf(
"FriendsList{Friends: %v}",
friends.FriendIds,
)
return common.FormatStruct(friends)
}

func NewFriendsList() *FriendsList {
Expand All @@ -262,8 +207,5 @@ type QuitResponse struct {
}

func (response QuitResponse) String() string {
return fmt.Sprintf(
"QuitResponse{UserId: %d}",
response.UserId,
)
return common.FormatStruct(response)
}
Loading

0 comments on commit 092a116

Please sign in to comment.