refactor: standardize logging on zap across all packages

Replace all fmt.Printf/Println and log.Printf/Fatal with structured
zap.Logger calls to eliminate inconsistent logging (anti-pattern #12).

- network/crypt_conn: inject logger via NewCryptConn, replace 6 fmt calls
- signserver/session: use existing s.logger for debug packet dumps
- entranceserver: use s.logger for inbound/outbound debug logging
- api/utils: accept logger param in verifyPath, replace fmt.Println
- api/endpoints: use s.logger for screenshot path diagnostics
- config: replace log.Fatal with error return in getOutboundIP4
- deltacomp: replace log.Printf with zap.L() global logger
This commit is contained in:
Houmgaor
2026-02-20 18:59:12 +01:00
parent e5133e5dcf
commit 06cb3afa57
15 changed files with 134 additions and 117 deletions

View File

@@ -5,8 +5,8 @@ import (
"encoding/json"
"encoding/xml"
"errors"
_config "erupe-ce/config"
"erupe-ce/common/gametime"
_config "erupe-ce/config"
"fmt"
"image"
"image/jpeg"
@@ -317,6 +317,7 @@ func (s *APIServer) ExportSave(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(save)
}
// ScreenShotGet handles GET /api/ss/bbs/{id}, serving a previously uploaded
// screenshot image by its token ID.
func (s *APIServer) ScreenShotGet(w http.ResponseWriter, r *http.Request) {
@@ -331,12 +332,12 @@ func (s *APIServer) ScreenShotGet(w http.ResponseWriter, r *http.Request) {
// Open the image file
safePath := s.erupeConfig.Screenshots.OutputDir
path := filepath.Join(safePath, fmt.Sprintf("%s.jpg", token))
result, err := verifyPath(path, safePath)
result, err := verifyPath(path, safePath, s.logger)
if err != nil {
fmt.Println("Error " + err.Error())
s.logger.Warn("Screenshot path verification failed", zap.Error(err))
} else {
fmt.Println("Canonical: " + result)
s.logger.Debug("Screenshot canonical path", zap.String("path", result))
file, err := os.Open(result)
if err != nil {
@@ -353,6 +354,7 @@ func (s *APIServer) ScreenShotGet(w http.ResponseWriter, r *http.Request) {
}
}
}
// ScreenShot handles POST /api/ss/bbs/upload.php, accepting a JPEG image
// upload from the game client and saving it to the configured output directory.
func (s *APIServer) ScreenShot(w http.ResponseWriter, r *http.Request) {
@@ -402,7 +404,7 @@ func (s *APIServer) ScreenShot(w http.ResponseWriter, r *http.Request) {
safePath := s.erupeConfig.Screenshots.OutputDir
path := filepath.Join(safePath, fmt.Sprintf("%s.jpg", token))
verified, err := verifyPath(path, safePath)
verified, err := verifyPath(path, safePath, s.logger)
if err != nil {
writeResult("500")
return

View File

@@ -35,13 +35,12 @@ func NewTestConfig() *_config.Config {
MaxLauncherHR: false,
},
GameplayOptions: _config.GameplayOptions{
MezFesSoloTickets: 100,
MezFesGroupTickets: 50,
MezFesDuration: 604800, // 1 week
MezFesSwitchMinigame: false,
MezFesSoloTickets: 100,
MezFesGroupTickets: 50,
MezFesDuration: 604800, // 1 week
MezFesSwitchMinigame: false,
},
LoginNotices: []string{"Welcome to Erupe!"},
LoginNotices: []string{"Welcome to Erupe!"},
HideLoginNotice: false,
}
}

View File

@@ -2,8 +2,9 @@ package api
import (
"errors"
"fmt"
"path/filepath"
"go.uber.org/zap"
)
func inTrustedRoot(path string, trustedRoot string) error {
@@ -16,20 +17,20 @@ func inTrustedRoot(path string, trustedRoot string) error {
return errors.New("path is outside of trusted root")
}
func verifyPath(path string, trustedRoot string) (string, error) {
func verifyPath(path string, trustedRoot string, logger *zap.Logger) (string, error) {
c := filepath.Clean(path)
fmt.Println("Cleaned path: " + c)
logger.Debug("Cleaned path", zap.String("path", c))
r, err := filepath.EvalSymlinks(c)
if err != nil {
fmt.Println("Error " + err.Error())
logger.Warn("Path verification failed", zap.Error(err))
return c, errors.New("unsafe or invalid path specified")
}
err = inTrustedRoot(r, trustedRoot)
if err != nil {
fmt.Println("Error " + err.Error())
logger.Warn("Path outside trusted root", zap.Error(err))
return r, errors.New("unsafe or invalid path specified")
} else {
return r, nil

View File

@@ -3,8 +3,10 @@ package api
import (
"os"
"path/filepath"
"testing"
"strings"
"testing"
"go.uber.org/zap"
)
func TestInTrustedRoot(t *testing.T) {
@@ -131,7 +133,7 @@ func TestVerifyPath(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := verifyPath(tt.path, tt.trustedRoot)
result, err := verifyPath(tt.path, tt.trustedRoot, zap.NewNop())
if (err != nil) != tt.wantErr {
t.Errorf("verifyPath() error = %v, wantErr %v", err, tt.wantErr)
}
@@ -171,7 +173,7 @@ func TestVerifyPathWithSymlinks(t *testing.T) {
}
// Verify that symlink pointing outside is detected
_, err := verifyPath(symlinkPath, safeDir)
_, err := verifyPath(symlinkPath, safeDir, zap.NewNop())
if err == nil {
t.Errorf("verifyPath() should reject symlink pointing outside trusted root")
}
@@ -188,7 +190,7 @@ func BenchmarkVerifyPath(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = verifyPath(testPath, safeDir)
_, _ = verifyPath(testPath, safeDir, zap.NewNop())
}
}

View File

@@ -3,7 +3,8 @@ package deltacomp
import (
"bytes"
"io"
"log"
"go.uber.org/zap"
)
func checkReadUint8(r *bytes.Reader) (uint8, error) {
@@ -77,7 +78,7 @@ func ApplyDataDiff(diff []byte, baseData []byte) []byte {
// Grow slice if it's required
if len(baseCopy) < dataOffset {
log.Printf("Slice smaller than data offset, growing slice...")
zap.L().Warn("Slice smaller than data offset, growing slice")
baseCopy = append(baseCopy, make([]byte, (dataOffset+differentCount)-len(baseData))...)
} else {
length := len(baseCopy[dataOffset:])

View File

@@ -104,7 +104,7 @@ func (s *Server) handleEntranceServerConnection(conn net.Conn) {
}
// Create a new encrypted connection handler and read a packet from it.
cc := network.NewCryptConn(conn, s.erupeConfig.RealClientMode)
cc := network.NewCryptConn(conn, s.erupeConfig.RealClientMode, s.logger)
pkt, err := cc.ReadPacket()
if err != nil {
s.logger.Warn("Error reading packet", zap.Error(err))
@@ -112,7 +112,7 @@ func (s *Server) handleEntranceServerConnection(conn net.Conn) {
}
if s.erupeConfig.DebugOptions.LogInboundMessages {
fmt.Printf("[Client] -> [Server]\nData [%d bytes]:\n%s\n", len(pkt), hex.Dump(pkt))
s.logger.Debug("Inbound packet", zap.Int("bytes", len(pkt)), zap.String("data", hex.Dump(pkt)))
}
local := strings.Split(conn.RemoteAddr().String(), ":")[0] == "127.0.0.1"

View File

@@ -5,11 +5,11 @@ import (
"encoding/hex"
"erupe-ce/common/stringsupport"
_config "erupe-ce/config"
"fmt"
"net"
"erupe-ce/common/byteframe"
"erupe-ce/common/gametime"
"go.uber.org/zap"
)
func encodeServerInfo(config *_config.Config, s *Server, local bool) []byte {
@@ -142,7 +142,7 @@ func makeSv2Resp(config *_config.Config, s *Server, local bool) []byte {
rawServerData := encodeServerInfo(config, s, local)
if s.erupeConfig.DebugOptions.LogOutboundMessages {
fmt.Printf("[Server] -> [Client]\nData [%d bytes]:\n%s\n", len(rawServerData), hex.Dump(rawServerData))
s.logger.Debug("Outbound SV2 response", zap.Int("bytes", len(rawServerData)), zap.String("data", hex.Dump(rawServerData)))
}
respType := "SV2"
@@ -174,7 +174,7 @@ func makeUsrResp(pkt []byte, s *Server) []byte {
}
if s.erupeConfig.DebugOptions.LogOutboundMessages {
fmt.Printf("[Server] -> [Client]\nData [%d bytes]:\n%s\n", len(resp.Data()), hex.Dump(resp.Data()))
s.logger.Debug("Outbound USR response", zap.Int("bytes", len(resp.Data())), zap.String("data", hex.Dump(resp.Data())))
}
return makeHeader(resp.Data(), "USR", userEntries, 0x00)

View File

@@ -4,7 +4,6 @@ import (
"database/sql"
"encoding/hex"
"erupe-ce/common/stringsupport"
"fmt"
"net"
"strings"
"sync"
@@ -40,7 +39,7 @@ func (s *Session) work() {
pkt, err := s.cryptConn.ReadPacket()
if s.server.erupeConfig.DebugOptions.LogInboundMessages {
fmt.Printf("\n[Client] -> [Server]\nData [%d bytes]:\n%s\n", len(pkt), hex.Dump(pkt))
s.logger.Debug("Inbound packet", zap.Int("bytes", len(pkt)), zap.String("data", hex.Dump(pkt)))
}
if err != nil {
@@ -84,7 +83,7 @@ func (s *Session) handlePacket(pkt []byte) error {
default:
s.logger.Warn("Unknown request", zap.String("reqType", reqType))
if s.server.erupeConfig.DebugOptions.LogInboundMessages {
fmt.Printf("\n[Client] -> [Server]\nData [%d bytes]:\n%s\n", len(pkt), hex.Dump(pkt))
s.logger.Debug("Unknown inbound packet", zap.Int("bytes", len(pkt)), zap.String("data", hex.Dump(pkt)))
}
}
return nil
@@ -108,7 +107,7 @@ func (s *Session) authenticate(username string, password string) {
bf.WriteUint8(uint8(resp))
}
if s.server.erupeConfig.DebugOptions.LogOutboundMessages {
fmt.Printf("\n[Server] -> [Client]\nData [%d bytes]:\n%s\n", len(bf.Data()), hex.Dump(bf.Data()))
s.logger.Debug("Outbound packet", zap.Int("bytes", len(bf.Data())), zap.String("data", hex.Dump(bf.Data())))
}
_ = s.cryptConn.SendPacket(bf.Data())
}

View File

@@ -64,8 +64,8 @@ func (m *mockConn) RemoteAddr() net.Addr {
}
func (m *mockConn) SetDeadline(t time.Time) error { return nil }
func (m *mockConn) SetReadDeadline(t time.Time) error { return nil }
func (m *mockConn) SetWriteDeadline(t time.Time) error { return nil }
func (m *mockConn) SetReadDeadline(t time.Time) error { return nil }
func (m *mockConn) SetWriteDeadline(t time.Time) error { return nil }
func TestSessionStruct(t *testing.T) {
logger := zap.NewNop()
@@ -75,7 +75,7 @@ func TestSessionStruct(t *testing.T) {
logger: logger,
server: nil,
rawConn: conn,
cryptConn: network.NewCryptConn(conn, _config.ZZ),
cryptConn: network.NewCryptConn(conn, _config.ZZ, nil),
}
if s.logger != logger {
@@ -132,8 +132,7 @@ func TestSessionMutex(t *testing.T) {
func TestHandlePacketUnknownRequest(t *testing.T) {
logger := zap.NewNop()
erupeConfig := &_config.Config{
}
erupeConfig := &_config.Config{}
server := &Server{
logger: logger,
@@ -145,7 +144,7 @@ func TestHandlePacketUnknownRequest(t *testing.T) {
logger: logger,
server: server,
rawConn: conn,
cryptConn: network.NewCryptConn(conn, _config.ZZ),
cryptConn: network.NewCryptConn(conn, _config.ZZ, nil),
}
bf := byteframe.NewByteFrame()
@@ -176,7 +175,7 @@ func TestHandlePacketWithDevModeLogging(t *testing.T) {
logger: logger,
server: server,
rawConn: conn,
cryptConn: network.NewCryptConn(conn, _config.ZZ),
cryptConn: network.NewCryptConn(conn, _config.ZZ, nil),
}
bf := byteframe.NewByteFrame()
@@ -214,7 +213,7 @@ func TestHandlePacketRequestTypes(t *testing.T) {
logger: logger,
server: server,
rawConn: conn,
cryptConn: network.NewCryptConn(conn, _config.ZZ),
cryptConn: network.NewCryptConn(conn, _config.ZZ, nil),
}
bf := byteframe.NewByteFrame()
@@ -324,7 +323,7 @@ func TestMockConnDeadlines(t *testing.T) {
func TestSessionWithCryptConn(t *testing.T) {
conn := newMockConn()
cryptConn := network.NewCryptConn(conn, _config.ZZ)
cryptConn := network.NewCryptConn(conn, _config.ZZ, nil)
if cryptConn == nil {
t.Fatal("NewCryptConn() returned nil")
@@ -361,7 +360,7 @@ func TestSessionWorkWithDevModeLogging(t *testing.T) {
logger: logger,
server: server,
rawConn: serverConn,
cryptConn: network.NewCryptConn(serverConn, _config.ZZ),
cryptConn: network.NewCryptConn(serverConn, _config.ZZ, nil),
}
_ = clientConn.Close()
@@ -371,8 +370,7 @@ func TestSessionWorkWithDevModeLogging(t *testing.T) {
func TestSessionWorkWithEmptyRead(t *testing.T) {
logger := zap.NewNop()
erupeConfig := &_config.Config{
}
erupeConfig := &_config.Config{}
server := &Server{
logger: logger,
@@ -386,7 +384,7 @@ func TestSessionWorkWithEmptyRead(t *testing.T) {
logger: logger,
server: server,
rawConn: serverConn,
cryptConn: network.NewCryptConn(serverConn, _config.ZZ),
cryptConn: network.NewCryptConn(serverConn, _config.ZZ, nil),
}
_ = clientConn.Close()

View File

@@ -101,7 +101,7 @@ func (s *Server) handleConnection(conn net.Conn) {
logger: s.logger,
server: s,
rawConn: conn,
cryptConn: network.NewCryptConn(conn, s.erupeConfig.RealClientMode),
cryptConn: network.NewCryptConn(conn, s.erupeConfig.RealClientMode, s.logger),
}
// Do the session's work.