mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-22 07:32:32 +01:00
refactor: extract gametime package, replace fmt.Printf with zap logging
Move time utilities (TimeAdjusted, TimeMidnight, TimeWeekStart, TimeWeekNext, TimeGameAbsolute) from channelserver into common/gametime to break the inappropriate dependency where signserver, entranceserver, and api imported the 38K-line channelserver package just for time functions. Replace all fmt.Printf debug logging in sys_session.go and handlers_object.go with structured zap logging for consistent observability.
This commit is contained in:
32
common/gametime/gametime.go
Normal file
32
common/gametime/gametime.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package gametime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Adjusted() time.Time {
|
||||||
|
baseTime := time.Now().In(time.FixedZone("UTC+9", 9*60*60))
|
||||||
|
return time.Date(baseTime.Year(), baseTime.Month(), baseTime.Day(), baseTime.Hour(), baseTime.Minute(), baseTime.Second(), baseTime.Nanosecond(), baseTime.Location())
|
||||||
|
}
|
||||||
|
|
||||||
|
func Midnight() time.Time {
|
||||||
|
baseTime := time.Now().In(time.FixedZone("UTC+9", 9*60*60))
|
||||||
|
return time.Date(baseTime.Year(), baseTime.Month(), baseTime.Day(), 0, 0, 0, 0, baseTime.Location())
|
||||||
|
}
|
||||||
|
|
||||||
|
func WeekStart() time.Time {
|
||||||
|
midnight := Midnight()
|
||||||
|
offset := int(midnight.Weekday()) - int(time.Monday)
|
||||||
|
if offset < 0 {
|
||||||
|
offset += 7
|
||||||
|
}
|
||||||
|
return midnight.Add(-time.Duration(offset) * 24 * time.Hour)
|
||||||
|
}
|
||||||
|
|
||||||
|
func WeekNext() time.Time {
|
||||||
|
return WeekStart().Add(time.Hour * 24 * 7)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GameAbsolute() uint32 {
|
||||||
|
return uint32((Adjusted().Unix() - 2160) % 5760)
|
||||||
|
}
|
||||||
157
common/gametime/gametime_test.go
Normal file
157
common/gametime/gametime_test.go
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
package gametime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAdjusted(t *testing.T) {
|
||||||
|
result := Adjusted()
|
||||||
|
|
||||||
|
_, offset := result.Zone()
|
||||||
|
expectedOffset := 9 * 60 * 60
|
||||||
|
if offset != expectedOffset {
|
||||||
|
t.Errorf("Adjusted() zone offset = %d, want %d (UTC+9)", offset, expectedOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
diff := result.Sub(now.In(time.FixedZone("UTC+9", 9*60*60)))
|
||||||
|
if diff < -time.Second || diff > time.Second {
|
||||||
|
t.Errorf("Adjusted() time differs from expected by %v", diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMidnight(t *testing.T) {
|
||||||
|
midnight := Midnight()
|
||||||
|
|
||||||
|
if midnight.Hour() != 0 {
|
||||||
|
t.Errorf("Midnight() hour = %d, want 0", midnight.Hour())
|
||||||
|
}
|
||||||
|
if midnight.Minute() != 0 {
|
||||||
|
t.Errorf("Midnight() minute = %d, want 0", midnight.Minute())
|
||||||
|
}
|
||||||
|
if midnight.Second() != 0 {
|
||||||
|
t.Errorf("Midnight() second = %d, want 0", midnight.Second())
|
||||||
|
}
|
||||||
|
if midnight.Nanosecond() != 0 {
|
||||||
|
t.Errorf("Midnight() nanosecond = %d, want 0", midnight.Nanosecond())
|
||||||
|
}
|
||||||
|
|
||||||
|
_, offset := midnight.Zone()
|
||||||
|
expectedOffset := 9 * 60 * 60
|
||||||
|
if offset != expectedOffset {
|
||||||
|
t.Errorf("Midnight() zone offset = %d, want %d (UTC+9)", offset, expectedOffset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWeekStart(t *testing.T) {
|
||||||
|
weekStart := WeekStart()
|
||||||
|
|
||||||
|
if weekStart.Weekday() != time.Monday {
|
||||||
|
t.Errorf("WeekStart() weekday = %v, want Monday", weekStart.Weekday())
|
||||||
|
}
|
||||||
|
|
||||||
|
if weekStart.Hour() != 0 || weekStart.Minute() != 0 || weekStart.Second() != 0 {
|
||||||
|
t.Errorf("WeekStart() should be at midnight, got %02d:%02d:%02d",
|
||||||
|
weekStart.Hour(), weekStart.Minute(), weekStart.Second())
|
||||||
|
}
|
||||||
|
|
||||||
|
_, offset := weekStart.Zone()
|
||||||
|
expectedOffset := 9 * 60 * 60
|
||||||
|
if offset != expectedOffset {
|
||||||
|
t.Errorf("WeekStart() zone offset = %d, want %d (UTC+9)", offset, expectedOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
midnight := Midnight()
|
||||||
|
if weekStart.After(midnight) {
|
||||||
|
t.Errorf("WeekStart() %v should be <= current midnight %v", weekStart, midnight)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWeekNext(t *testing.T) {
|
||||||
|
weekStart := WeekStart()
|
||||||
|
weekNext := WeekNext()
|
||||||
|
|
||||||
|
expectedNext := weekStart.Add(time.Hour * 24 * 7)
|
||||||
|
if !weekNext.Equal(expectedNext) {
|
||||||
|
t.Errorf("WeekNext() = %v, want %v (7 days after WeekStart)", weekNext, expectedNext)
|
||||||
|
}
|
||||||
|
|
||||||
|
if weekNext.Weekday() != time.Monday {
|
||||||
|
t.Errorf("WeekNext() weekday = %v, want Monday", weekNext.Weekday())
|
||||||
|
}
|
||||||
|
|
||||||
|
if weekNext.Hour() != 0 || weekNext.Minute() != 0 || weekNext.Second() != 0 {
|
||||||
|
t.Errorf("WeekNext() should be at midnight, got %02d:%02d:%02d",
|
||||||
|
weekNext.Hour(), weekNext.Minute(), weekNext.Second())
|
||||||
|
}
|
||||||
|
|
||||||
|
if !weekNext.After(weekStart) {
|
||||||
|
t.Errorf("WeekNext() %v should be after WeekStart() %v", weekNext, weekStart)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWeekStartSundayEdge(t *testing.T) {
|
||||||
|
weekStart := WeekStart()
|
||||||
|
|
||||||
|
if weekStart.Weekday() != time.Monday {
|
||||||
|
t.Errorf("WeekStart() on any day should return Monday, got %v", weekStart.Weekday())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMidnightSameDay(t *testing.T) {
|
||||||
|
adjusted := Adjusted()
|
||||||
|
midnight := Midnight()
|
||||||
|
|
||||||
|
if midnight.Year() != adjusted.Year() ||
|
||||||
|
midnight.Month() != adjusted.Month() ||
|
||||||
|
midnight.Day() != adjusted.Day() {
|
||||||
|
t.Errorf("Midnight() date = %v, want same day as Adjusted() %v",
|
||||||
|
midnight.Format("2006-01-02"), adjusted.Format("2006-01-02"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWeekDuration(t *testing.T) {
|
||||||
|
weekStart := WeekStart()
|
||||||
|
weekNext := WeekNext()
|
||||||
|
|
||||||
|
duration := weekNext.Sub(weekStart)
|
||||||
|
expectedDuration := time.Hour * 24 * 7
|
||||||
|
|
||||||
|
if duration != expectedDuration {
|
||||||
|
t.Errorf("Duration between WeekStart and WeekNext = %v, want %v", duration, expectedDuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTimeZoneConsistency(t *testing.T) {
|
||||||
|
adjusted := Adjusted()
|
||||||
|
midnight := Midnight()
|
||||||
|
weekStart := WeekStart()
|
||||||
|
weekNext := WeekNext()
|
||||||
|
|
||||||
|
times := []struct {
|
||||||
|
name string
|
||||||
|
time time.Time
|
||||||
|
}{
|
||||||
|
{"Adjusted", adjusted},
|
||||||
|
{"Midnight", midnight},
|
||||||
|
{"WeekStart", weekStart},
|
||||||
|
{"WeekNext", weekNext},
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOffset := 9 * 60 * 60
|
||||||
|
for _, tt := range times {
|
||||||
|
_, offset := tt.time.Zone()
|
||||||
|
if offset != expectedOffset {
|
||||||
|
t.Errorf("%s() zone offset = %d, want %d (UTC+9)", tt.name, offset, expectedOffset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGameAbsolute(t *testing.T) {
|
||||||
|
result := GameAbsolute()
|
||||||
|
|
||||||
|
if result >= 5760 {
|
||||||
|
t.Errorf("GameAbsolute() = %d, should be < 5760", result)
|
||||||
|
}
|
||||||
|
}
|
||||||
3
main.go
3
main.go
@@ -10,6 +10,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"erupe-ce/common/gametime"
|
||||||
"erupe-ce/server/api"
|
"erupe-ce/server/api"
|
||||||
"erupe-ce/server/channelserver"
|
"erupe-ce/server/channelserver"
|
||||||
"erupe-ce/server/discordbot"
|
"erupe-ce/server/discordbot"
|
||||||
@@ -142,7 +143,7 @@ func main() {
|
|||||||
logger.Info("Database: Finished clearing")
|
logger.Info("Database: Finished clearing")
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info(fmt.Sprintf("Server Time: %s", channelserver.TimeAdjusted().String()))
|
logger.Info(fmt.Sprintf("Server Time: %s", gametime.Adjusted().String()))
|
||||||
|
|
||||||
// Now start our server(s).
|
// Now start our server(s).
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package clientctx
|
package clientctx
|
||||||
|
|
||||||
// ClientContext holds contextual data required for packet encoding/decoding.
|
// ClientContext holds contextual data required for packet encoding/decoding.
|
||||||
type ClientContext struct{} // Unused
|
type ClientContext struct{}
|
||||||
|
|||||||
@@ -5,27 +5,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// TestClientContext_Exists verifies that the ClientContext type exists
|
// TestClientContext_Exists verifies that the ClientContext type exists
|
||||||
// and can be instantiated, even though it's currently unused.
|
// and can be instantiated.
|
||||||
func TestClientContext_Exists(t *testing.T) {
|
func TestClientContext_Exists(t *testing.T) {
|
||||||
// This test documents that ClientContext is currently an empty struct
|
|
||||||
// and is marked as unused in the codebase.
|
|
||||||
var ctx ClientContext
|
|
||||||
|
|
||||||
// Verify it's a zero-size struct
|
|
||||||
_ = ctx
|
|
||||||
|
|
||||||
// Just verify we can create it
|
|
||||||
ctx2 := ClientContext{}
|
|
||||||
_ = ctx2
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestClientContext_IsEmpty verifies that ClientContext has no fields
|
|
||||||
func TestClientContext_IsEmpty(t *testing.T) {
|
|
||||||
// The struct should be empty as marked by the comment "// Unused"
|
|
||||||
// This test documents the current state of the struct
|
|
||||||
ctx := ClientContext{}
|
ctx := ClientContext{}
|
||||||
_ = ctx
|
_ = ctx
|
||||||
|
|
||||||
// If fields are added in the future, this test will need to be updated
|
|
||||||
// Currently it's just a placeholder/documentation test
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"errors"
|
"errors"
|
||||||
_config "erupe-ce/config"
|
_config "erupe-ce/config"
|
||||||
"erupe-ce/server/channelserver"
|
"erupe-ce/common/gametime"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"image/jpeg"
|
"image/jpeg"
|
||||||
@@ -77,7 +77,7 @@ type ExportData struct {
|
|||||||
|
|
||||||
func (s *APIServer) newAuthData(userID uint32, userRights uint32, userTokenID uint32, userToken string, characters []Character) AuthData {
|
func (s *APIServer) newAuthData(userID uint32, userRights uint32, userTokenID uint32, userToken string, characters []Character) AuthData {
|
||||||
resp := AuthData{
|
resp := AuthData{
|
||||||
CurrentTS: uint32(channelserver.TimeAdjusted().Unix()),
|
CurrentTS: uint32(gametime.Adjusted().Unix()),
|
||||||
ExpiryTS: uint32(s.getReturnExpiry(userID).Unix()),
|
ExpiryTS: uint32(s.getReturnExpiry(userID).Unix()),
|
||||||
EntranceCount: 1,
|
EntranceCount: 1,
|
||||||
User: User{
|
User: User{
|
||||||
@@ -99,9 +99,9 @@ func (s *APIServer) newAuthData(userID uint32, userRights uint32, userTokenID ui
|
|||||||
stalls[4] = 2
|
stalls[4] = 2
|
||||||
}
|
}
|
||||||
resp.MezFes = &MezFes{
|
resp.MezFes = &MezFes{
|
||||||
ID: uint32(channelserver.TimeWeekStart().Unix()),
|
ID: uint32(gametime.WeekStart().Unix()),
|
||||||
Start: uint32(channelserver.TimeWeekStart().Add(-time.Duration(s.erupeConfig.GameplayOptions.MezFesDuration) * time.Second).Unix()),
|
Start: uint32(gametime.WeekStart().Add(-time.Duration(s.erupeConfig.GameplayOptions.MezFesDuration) * time.Second).Unix()),
|
||||||
End: uint32(channelserver.TimeWeekNext().Unix()),
|
End: uint32(gametime.WeekNext().Unix()),
|
||||||
SoloTickets: s.erupeConfig.GameplayOptions.MezFesSoloTickets,
|
SoloTickets: s.erupeConfig.GameplayOptions.MezFesSoloTickets,
|
||||||
GroupTickets: s.erupeConfig.GameplayOptions.MezFesGroupTickets,
|
GroupTickets: s.erupeConfig.GameplayOptions.MezFesGroupTickets,
|
||||||
Stalls: stalls,
|
Stalls: stalls,
|
||||||
@@ -118,7 +118,7 @@ func (s *APIServer) Launcher(w http.ResponseWriter, r *http.Request) {
|
|||||||
respData.Messages = s.erupeConfig.API.Messages
|
respData.Messages = s.erupeConfig.API.Messages
|
||||||
respData.Links = s.erupeConfig.API.Links
|
respData.Links = s.erupeConfig.API.Links
|
||||||
w.Header().Add("Content-Type", "application/json")
|
w.Header().Add("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(respData)
|
_ = json.NewEncoder(w).Encode(respData)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *APIServer) Login(w http.ResponseWriter, r *http.Request) {
|
func (s *APIServer) Login(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -140,7 +140,7 @@ func (s *APIServer) Login(w http.ResponseWriter, r *http.Request) {
|
|||||||
err := s.db.QueryRow("SELECT id, password, rights FROM users WHERE username = $1", reqData.Username).Scan(&userID, &password, &userRights)
|
err := s.db.QueryRow("SELECT id, password, rights FROM users WHERE username = $1", reqData.Username).Scan(&userID, &password, &userRights)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
w.WriteHeader(400)
|
w.WriteHeader(400)
|
||||||
w.Write([]byte("username-error"))
|
_, _ = w.Write([]byte("username-error"))
|
||||||
return
|
return
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
s.logger.Warn("SQL query error", zap.Error(err))
|
s.logger.Warn("SQL query error", zap.Error(err))
|
||||||
@@ -149,7 +149,7 @@ func (s *APIServer) Login(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
if bcrypt.CompareHashAndPassword([]byte(password), []byte(reqData.Password)) != nil {
|
if bcrypt.CompareHashAndPassword([]byte(password), []byte(reqData.Password)) != nil {
|
||||||
w.WriteHeader(400)
|
w.WriteHeader(400)
|
||||||
w.Write([]byte("password-error"))
|
_, _ = w.Write([]byte("password-error"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ func (s *APIServer) Login(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
respData := s.newAuthData(userID, userRights, userTokenID, userToken, characters)
|
respData := s.newAuthData(userID, userRights, userTokenID, userToken, characters)
|
||||||
w.Header().Add("Content-Type", "application/json")
|
w.Header().Add("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(respData)
|
_ = json.NewEncoder(w).Encode(respData)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *APIServer) Register(w http.ResponseWriter, r *http.Request) {
|
func (s *APIServer) Register(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -194,7 +194,7 @@ func (s *APIServer) Register(w http.ResponseWriter, r *http.Request) {
|
|||||||
var pqErr *pq.Error
|
var pqErr *pq.Error
|
||||||
if errors.As(err, &pqErr) && pqErr.Constraint == "users_username_key" {
|
if errors.As(err, &pqErr) && pqErr.Constraint == "users_username_key" {
|
||||||
w.WriteHeader(400)
|
w.WriteHeader(400)
|
||||||
w.Write([]byte("username-exists-error"))
|
_, _ = w.Write([]byte("username-exists-error"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.logger.Error("Error checking user", zap.Error(err), zap.String("username", reqData.Username))
|
s.logger.Error("Error checking user", zap.Error(err), zap.String("username", reqData.Username))
|
||||||
@@ -210,7 +210,7 @@ func (s *APIServer) Register(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
respData := s.newAuthData(userID, userRights, userTokenID, userToken, []Character{})
|
respData := s.newAuthData(userID, userRights, userTokenID, userToken, []Character{})
|
||||||
w.Header().Add("Content-Type", "application/json")
|
w.Header().Add("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(respData)
|
_ = json.NewEncoder(w).Encode(respData)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *APIServer) CreateCharacter(w http.ResponseWriter, r *http.Request) {
|
func (s *APIServer) CreateCharacter(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -239,7 +239,7 @@ func (s *APIServer) CreateCharacter(w http.ResponseWriter, r *http.Request) {
|
|||||||
character.HR = 7
|
character.HR = 7
|
||||||
}
|
}
|
||||||
w.Header().Add("Content-Type", "application/json")
|
w.Header().Add("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(character)
|
_ = json.NewEncoder(w).Encode(character)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *APIServer) DeleteCharacter(w http.ResponseWriter, r *http.Request) {
|
func (s *APIServer) DeleteCharacter(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -264,7 +264,7 @@ func (s *APIServer) DeleteCharacter(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Header().Add("Content-Type", "application/json")
|
w.Header().Add("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(struct{}{})
|
_ = json.NewEncoder(w).Encode(struct{}{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *APIServer) ExportSave(w http.ResponseWriter, r *http.Request) {
|
func (s *APIServer) ExportSave(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -293,7 +293,7 @@ func (s *APIServer) ExportSave(w http.ResponseWriter, r *http.Request) {
|
|||||||
Character: character,
|
Character: character,
|
||||||
}
|
}
|
||||||
w.Header().Add("Content-Type", "application/json")
|
w.Header().Add("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(save)
|
_ = json.NewEncoder(w).Encode(save)
|
||||||
}
|
}
|
||||||
func (s *APIServer) ScreenShotGet(w http.ResponseWriter, r *http.Request) {
|
func (s *APIServer) ScreenShotGet(w http.ResponseWriter, r *http.Request) {
|
||||||
// Get the 'id' parameter from the URL
|
// Get the 'id' parameter from the URL
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
_config "erupe-ce/config"
|
_config "erupe-ce/config"
|
||||||
"erupe-ce/server/channelserver"
|
"erupe-ce/common/gametime"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ func TestLauncherEndpointEmptyConfig(t *testing.T) {
|
|||||||
server.Launcher(recorder, req)
|
server.Launcher(recorder, req)
|
||||||
|
|
||||||
var respData LauncherResponse
|
var respData LauncherResponse
|
||||||
json.NewDecoder(recorder.Body).Decode(&respData)
|
_ = json.NewDecoder(recorder.Body).Decode(&respData)
|
||||||
|
|
||||||
if respData.Banners == nil {
|
if respData.Banners == nil {
|
||||||
t.Error("Banners should not be nil, should be empty slice")
|
t.Error("Banners should not be nil, should be empty slice")
|
||||||
@@ -355,7 +355,7 @@ func TestScreenShotEndpointDisabled(t *testing.T) {
|
|||||||
XMLName xml.Name `xml:"result"`
|
XMLName xml.Name `xml:"result"`
|
||||||
Code string `xml:"code"`
|
Code string `xml:"code"`
|
||||||
}
|
}
|
||||||
xml.NewDecoder(recorder.Body).Decode(&result)
|
_ = xml.NewDecoder(recorder.Body).Decode(&result)
|
||||||
|
|
||||||
if result.Code != "400" {
|
if result.Code != "400" {
|
||||||
t.Errorf("Expected code 400, got %s", result.Code)
|
t.Errorf("Expected code 400, got %s", result.Code)
|
||||||
@@ -573,7 +573,7 @@ func TestNewAuthDataTimestamps(t *testing.T) {
|
|||||||
authData := server.newAuthData(1, 0, 1, "token", []Character{})
|
authData := server.newAuthData(1, 0, 1, "token", []Character{})
|
||||||
|
|
||||||
// Timestamps should be reasonable (within last minute and next 30 days)
|
// Timestamps should be reasonable (within last minute and next 30 days)
|
||||||
now := uint32(channelserver.TimeAdjusted().Unix())
|
now := uint32(gametime.Adjusted().Unix())
|
||||||
if authData.CurrentTS < now-60 || authData.CurrentTS > now+60 {
|
if authData.CurrentTS < now-60 || authData.CurrentTS > now+60 {
|
||||||
t.Errorf("CurrentTS not within reasonable range: %d vs %d", authData.CurrentTS, now)
|
t.Errorf("CurrentTS not within reasonable range: %d vs %d", authData.CurrentTS, now)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package deltacomp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkReadUint8(r *bytes.Reader) (uint8, error) {
|
func checkReadUint8(r *bytes.Reader) (uint8, error) {
|
||||||
@@ -77,7 +77,7 @@ func ApplyDataDiff(diff []byte, baseData []byte) []byte {
|
|||||||
|
|
||||||
// Grow slice if it's required
|
// Grow slice if it's required
|
||||||
if len(baseCopy) < dataOffset {
|
if len(baseCopy) < dataOffset {
|
||||||
fmt.Printf("Slice smaller than data offset, growing slice...")
|
log.Printf("Slice smaller than data offset, growing slice...")
|
||||||
baseCopy = append(baseCopy, make([]byte, (dataOffset+differentCount)-len(baseData))...)
|
baseCopy = append(baseCopy, make([]byte, (dataOffset+differentCount)-len(baseData))...)
|
||||||
} else {
|
} else {
|
||||||
length := len(baseCopy[dataOffset:])
|
length := len(baseCopy[dataOffset:])
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package channelserver
|
package channelserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
"erupe-ce/network/mhfpacket"
|
"erupe-ce/network/mhfpacket"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
func handleMsgSysCreateObject(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgSysCreateObject(s *Session, p mhfpacket.MHFPacket) {
|
||||||
@@ -34,7 +34,7 @@ func handleMsgSysCreateObject(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
OwnerCharID: newObj.ownerCharID,
|
OwnerCharID: newObj.ownerCharID,
|
||||||
}
|
}
|
||||||
|
|
||||||
s.logger.Info(fmt.Sprintf("Broadcasting new object: %s (%d)", s.Name, newObj.id))
|
s.logger.Info("Broadcasting new object", zap.String("name", s.Name), zap.Uint32("objectID", newObj.id))
|
||||||
s.stage.BroadcastMHF(dupObjUpdate, s)
|
s.stage.BroadcastMHF(dupObjUpdate, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +43,13 @@ func handleMsgSysDeleteObject(s *Session, p mhfpacket.MHFPacket) {}
|
|||||||
func handleMsgSysPositionObject(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgSysPositionObject(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgSysPositionObject)
|
pkt := p.(*mhfpacket.MsgSysPositionObject)
|
||||||
if s.server.erupeConfig.DebugOptions.LogInboundMessages {
|
if s.server.erupeConfig.DebugOptions.LogInboundMessages {
|
||||||
fmt.Printf("[%s] with objectID [%d] move to (%f,%f,%f)\n\n", s.Name, pkt.ObjID, pkt.X, pkt.Y, pkt.Z)
|
s.logger.Debug("Object position update",
|
||||||
|
zap.String("name", s.Name),
|
||||||
|
zap.Uint32("objectID", pkt.ObjID),
|
||||||
|
zap.Float32("x", pkt.X),
|
||||||
|
zap.Float32("y", pkt.Y),
|
||||||
|
zap.Float32("z", pkt.Z),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
s.stage.Lock()
|
s.stage.Lock()
|
||||||
object, ok := s.stage.objects[s.charID]
|
object, ok := s.stage.objects[s.charID]
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ func NewSession(server *Server, conn net.Conn) *Session {
|
|||||||
rawConn: conn,
|
rawConn: conn,
|
||||||
cryptConn: network.NewCryptConn(conn),
|
cryptConn: network.NewCryptConn(conn),
|
||||||
sendPackets: make(chan packet, 20),
|
sendPackets: make(chan packet, 20),
|
||||||
clientContext: &clientctx.ClientContext{}, // Unused
|
clientContext: &clientctx.ClientContext{},
|
||||||
lastPacket: time.Now(),
|
lastPacket: time.Now(),
|
||||||
objectID: server.getObjectId(),
|
objectID: server.getObjectId(),
|
||||||
sessionStart: TimeAdjusted().Unix(),
|
sessionStart: TimeAdjusted().Unix(),
|
||||||
@@ -232,8 +232,7 @@ func (s *Session) handlePacketGroup(pktGroup []byte) {
|
|||||||
// This shouldn't be needed, but it's better to recover and let the connection die than to panic the server.
|
// This shouldn't be needed, but it's better to recover and let the connection die than to panic the server.
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
fmt.Printf("[%s]", s.Name)
|
s.logger.Error("Recovered from panic", zap.String("name", s.Name), zap.Any("panic", r))
|
||||||
fmt.Println("Recovered from panic", r)
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -246,13 +245,16 @@ func (s *Session) handlePacketGroup(pktGroup []byte) {
|
|||||||
// Get the packet parser and handler for this opcode.
|
// Get the packet parser and handler for this opcode.
|
||||||
mhfPkt := mhfpacket.FromOpcode(opcode)
|
mhfPkt := mhfpacket.FromOpcode(opcode)
|
||||||
if mhfPkt == nil {
|
if mhfPkt == nil {
|
||||||
fmt.Println("Got opcode which we don't know how to parse, can't parse anymore for this group")
|
s.logger.Warn("Got opcode which we don't know how to parse, can't parse anymore for this group")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Parse the packet.
|
// Parse the packet.
|
||||||
err := mhfPkt.Parse(bf, s.clientContext)
|
err := mhfPkt.Parse(bf, s.clientContext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("\n!!! [%s] %s NOT IMPLEMENTED !!! \n\n\n", s.Name, opcode)
|
s.logger.Warn("Packet not implemented",
|
||||||
|
zap.String("name", s.Name),
|
||||||
|
zap.Stringer("opcode", opcode),
|
||||||
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Handle the packet.
|
// Handle the packet.
|
||||||
@@ -297,21 +299,23 @@ func (s *Session) logMessage(opcode uint16, data []byte, sender string, recipien
|
|||||||
if len(data) >= 6 {
|
if len(data) >= 6 {
|
||||||
ackHandle = binary.BigEndian.Uint32(data[2:6])
|
ackHandle = binary.BigEndian.Uint32(data[2:6])
|
||||||
}
|
}
|
||||||
if t, ok := s.ackStart[ackHandle]; ok {
|
fields := []zap.Field{
|
||||||
fmt.Printf("[%s] -> [%s] (%fs)\n", sender, recipient, float64(time.Now().UnixNano()-t.UnixNano())/1000000000)
|
zap.String("sender", sender),
|
||||||
} else {
|
zap.String("recipient", recipient),
|
||||||
fmt.Printf("[%s] -> [%s]\n", sender, recipient)
|
zap.Uint16("opcode_dec", opcode),
|
||||||
|
zap.String("opcode_hex", fmt.Sprintf("0x%04X", opcode)),
|
||||||
|
zap.Stringer("opcode_name", opcodePID),
|
||||||
|
zap.Int("data_bytes", len(data)),
|
||||||
|
}
|
||||||
|
if t, ok := s.ackStart[ackHandle]; ok {
|
||||||
|
fields = append(fields, zap.Duration("ack_latency", time.Since(t)))
|
||||||
}
|
}
|
||||||
fmt.Printf("Opcode: (Dec: %d Hex: 0x%04X Name: %s) \n", opcode, opcode, opcodePID)
|
|
||||||
if s.server.erupeConfig.DebugOptions.LogMessageData {
|
if s.server.erupeConfig.DebugOptions.LogMessageData {
|
||||||
if len(data) <= s.server.erupeConfig.DebugOptions.MaxHexdumpLength {
|
if len(data) <= s.server.erupeConfig.DebugOptions.MaxHexdumpLength {
|
||||||
fmt.Printf("Data [%d bytes]:\n%s\n", len(data), hex.Dump(data))
|
fields = append(fields, zap.String("data", hex.Dump(data)))
|
||||||
} else {
|
|
||||||
fmt.Printf("Data [%d bytes]: (Too long!)\n\n", len(data))
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
fmt.Printf("\n")
|
|
||||||
}
|
}
|
||||||
|
s.logger.Debug("Packet", fields...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) getObjectId() uint32 {
|
func (s *Session) getObjectId() uint32 {
|
||||||
|
|||||||
@@ -1,32 +1,12 @@
|
|||||||
package channelserver
|
package channelserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"erupe-ce/common/gametime"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TimeAdjusted() time.Time {
|
func TimeAdjusted() time.Time { return gametime.Adjusted() }
|
||||||
baseTime := time.Now().In(time.FixedZone("UTC+9", 9*60*60))
|
func TimeMidnight() time.Time { return gametime.Midnight() }
|
||||||
return time.Date(baseTime.Year(), baseTime.Month(), baseTime.Day(), baseTime.Hour(), baseTime.Minute(), baseTime.Second(), baseTime.Nanosecond(), baseTime.Location())
|
func TimeWeekStart() time.Time { return gametime.WeekStart() }
|
||||||
}
|
func TimeWeekNext() time.Time { return gametime.WeekNext() }
|
||||||
|
func TimeGameAbsolute() uint32 { return gametime.GameAbsolute() }
|
||||||
func TimeMidnight() time.Time {
|
|
||||||
baseTime := time.Now().In(time.FixedZone("UTC+9", 9*60*60))
|
|
||||||
return time.Date(baseTime.Year(), baseTime.Month(), baseTime.Day(), 0, 0, 0, 0, baseTime.Location())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TimeWeekStart() time.Time {
|
|
||||||
midnight := TimeMidnight()
|
|
||||||
offset := int(midnight.Weekday()) - int(time.Monday)
|
|
||||||
if offset < 0 {
|
|
||||||
offset += 7
|
|
||||||
}
|
|
||||||
return midnight.Add(-time.Duration(offset) * 24 * time.Hour)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TimeWeekNext() time.Time {
|
|
||||||
return TimeWeekStart().Add(time.Hour * 24 * 7)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TimeGameAbsolute() uint32 {
|
|
||||||
return uint32((TimeAdjusted().Unix() - 2160) % 5760)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,167 +0,0 @@
|
|||||||
package channelserver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestTimeAdjusted(t *testing.T) {
|
|
||||||
result := TimeAdjusted()
|
|
||||||
|
|
||||||
// Should return a time in UTC+9 timezone
|
|
||||||
_, offset := result.Zone()
|
|
||||||
expectedOffset := 9 * 60 * 60 // 9 hours in seconds
|
|
||||||
if offset != expectedOffset {
|
|
||||||
t.Errorf("TimeAdjusted() zone offset = %d, want %d (UTC+9)", offset, expectedOffset)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The time should be close to current time (within a few seconds)
|
|
||||||
now := time.Now()
|
|
||||||
diff := result.Sub(now.In(time.FixedZone("UTC+9", 9*60*60)))
|
|
||||||
if diff < -time.Second || diff > time.Second {
|
|
||||||
t.Errorf("TimeAdjusted() time differs from expected by %v", diff)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTimeMidnight(t *testing.T) {
|
|
||||||
midnight := TimeMidnight()
|
|
||||||
|
|
||||||
// Should be at midnight (hour=0, minute=0, second=0, nanosecond=0)
|
|
||||||
if midnight.Hour() != 0 {
|
|
||||||
t.Errorf("TimeMidnight() hour = %d, want 0", midnight.Hour())
|
|
||||||
}
|
|
||||||
if midnight.Minute() != 0 {
|
|
||||||
t.Errorf("TimeMidnight() minute = %d, want 0", midnight.Minute())
|
|
||||||
}
|
|
||||||
if midnight.Second() != 0 {
|
|
||||||
t.Errorf("TimeMidnight() second = %d, want 0", midnight.Second())
|
|
||||||
}
|
|
||||||
if midnight.Nanosecond() != 0 {
|
|
||||||
t.Errorf("TimeMidnight() nanosecond = %d, want 0", midnight.Nanosecond())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Should be in UTC+9 timezone
|
|
||||||
_, offset := midnight.Zone()
|
|
||||||
expectedOffset := 9 * 60 * 60
|
|
||||||
if offset != expectedOffset {
|
|
||||||
t.Errorf("TimeMidnight() zone offset = %d, want %d (UTC+9)", offset, expectedOffset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTimeWeekStart(t *testing.T) {
|
|
||||||
weekStart := TimeWeekStart()
|
|
||||||
|
|
||||||
// Should be on Monday (weekday = 1)
|
|
||||||
if weekStart.Weekday() != time.Monday {
|
|
||||||
t.Errorf("TimeWeekStart() weekday = %v, want Monday", weekStart.Weekday())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Should be at midnight
|
|
||||||
if weekStart.Hour() != 0 || weekStart.Minute() != 0 || weekStart.Second() != 0 {
|
|
||||||
t.Errorf("TimeWeekStart() should be at midnight, got %02d:%02d:%02d",
|
|
||||||
weekStart.Hour(), weekStart.Minute(), weekStart.Second())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Should be in UTC+9 timezone
|
|
||||||
_, offset := weekStart.Zone()
|
|
||||||
expectedOffset := 9 * 60 * 60
|
|
||||||
if offset != expectedOffset {
|
|
||||||
t.Errorf("TimeWeekStart() zone offset = %d, want %d (UTC+9)", offset, expectedOffset)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Week start should be before or equal to current midnight
|
|
||||||
midnight := TimeMidnight()
|
|
||||||
if weekStart.After(midnight) {
|
|
||||||
t.Errorf("TimeWeekStart() %v should be <= current midnight %v", weekStart, midnight)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTimeWeekNext(t *testing.T) {
|
|
||||||
weekStart := TimeWeekStart()
|
|
||||||
weekNext := TimeWeekNext()
|
|
||||||
|
|
||||||
// TimeWeekNext should be exactly 7 days after TimeWeekStart
|
|
||||||
expectedNext := weekStart.Add(time.Hour * 24 * 7)
|
|
||||||
if !weekNext.Equal(expectedNext) {
|
|
||||||
t.Errorf("TimeWeekNext() = %v, want %v (7 days after WeekStart)", weekNext, expectedNext)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Should also be on Monday
|
|
||||||
if weekNext.Weekday() != time.Monday {
|
|
||||||
t.Errorf("TimeWeekNext() weekday = %v, want Monday", weekNext.Weekday())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Should be at midnight
|
|
||||||
if weekNext.Hour() != 0 || weekNext.Minute() != 0 || weekNext.Second() != 0 {
|
|
||||||
t.Errorf("TimeWeekNext() should be at midnight, got %02d:%02d:%02d",
|
|
||||||
weekNext.Hour(), weekNext.Minute(), weekNext.Second())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Should be in the future relative to week start
|
|
||||||
if !weekNext.After(weekStart) {
|
|
||||||
t.Errorf("TimeWeekNext() %v should be after TimeWeekStart() %v", weekNext, weekStart)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTimeWeekStartSundayEdge(t *testing.T) {
|
|
||||||
// When today is Sunday, the calculation should go back to last Monday
|
|
||||||
// This is tested indirectly by verifying the weekday is always Monday
|
|
||||||
weekStart := TimeWeekStart()
|
|
||||||
|
|
||||||
// Regardless of what day it is now, week start should be Monday
|
|
||||||
if weekStart.Weekday() != time.Monday {
|
|
||||||
t.Errorf("TimeWeekStart() on any day should return Monday, got %v", weekStart.Weekday())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTimeMidnightSameDay(t *testing.T) {
|
|
||||||
adjusted := TimeAdjusted()
|
|
||||||
midnight := TimeMidnight()
|
|
||||||
|
|
||||||
// Midnight should be on the same day (year, month, day)
|
|
||||||
if midnight.Year() != adjusted.Year() ||
|
|
||||||
midnight.Month() != adjusted.Month() ||
|
|
||||||
midnight.Day() != adjusted.Day() {
|
|
||||||
t.Errorf("TimeMidnight() date = %v, want same day as TimeAdjusted() %v",
|
|
||||||
midnight.Format("2006-01-02"), adjusted.Format("2006-01-02"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTimeWeekDuration(t *testing.T) {
|
|
||||||
weekStart := TimeWeekStart()
|
|
||||||
weekNext := TimeWeekNext()
|
|
||||||
|
|
||||||
// Duration between week boundaries should be exactly 7 days
|
|
||||||
duration := weekNext.Sub(weekStart)
|
|
||||||
expectedDuration := time.Hour * 24 * 7
|
|
||||||
|
|
||||||
if duration != expectedDuration {
|
|
||||||
t.Errorf("Duration between WeekStart and WeekNext = %v, want %v", duration, expectedDuration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTimeZoneConsistency(t *testing.T) {
|
|
||||||
adjusted := TimeAdjusted()
|
|
||||||
midnight := TimeMidnight()
|
|
||||||
weekStart := TimeWeekStart()
|
|
||||||
weekNext := TimeWeekNext()
|
|
||||||
|
|
||||||
// All times should be in the same timezone (UTC+9)
|
|
||||||
times := []struct {
|
|
||||||
name string
|
|
||||||
time time.Time
|
|
||||||
}{
|
|
||||||
{"TimeAdjusted", adjusted},
|
|
||||||
{"TimeMidnight", midnight},
|
|
||||||
{"TimeWeekStart", weekStart},
|
|
||||||
{"TimeWeekNext", weekNext},
|
|
||||||
}
|
|
||||||
|
|
||||||
expectedOffset := 9 * 60 * 60
|
|
||||||
for _, tt := range times {
|
|
||||||
_, offset := tt.time.Zone()
|
|
||||||
if offset != expectedOffset {
|
|
||||||
t.Errorf("%s() zone offset = %d, want %d (UTC+9)", tt.name, offset, expectedOffset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
"erupe-ce/server/channelserver"
|
"erupe-ce/common/gametime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func encodeServerInfo(config *_config.Config, s *Server, local bool) []byte {
|
func encodeServerInfo(config *_config.Config, s *Server, local bool) []byte {
|
||||||
@@ -41,7 +41,7 @@ func encodeServerInfo(config *_config.Config, s *Server, local bool) []byte {
|
|||||||
bf.WriteUint16(0)
|
bf.WriteUint16(0)
|
||||||
bf.WriteUint16(uint16(len(si.Channels)))
|
bf.WriteUint16(uint16(len(si.Channels)))
|
||||||
bf.WriteUint8(si.Type)
|
bf.WriteUint8(si.Type)
|
||||||
bf.WriteUint8(uint8(((channelserver.TimeAdjusted().Unix() / 86400) + int64(serverIdx)) % 3))
|
bf.WriteUint8(uint8(((gametime.Adjusted().Unix() / 86400) + int64(serverIdx)) % 3))
|
||||||
if s.erupeConfig.RealClientMode >= _config.G1 {
|
if s.erupeConfig.RealClientMode >= _config.G1 {
|
||||||
bf.WriteUint8(si.Recommended)
|
bf.WriteUint8(si.Recommended)
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ func encodeServerInfo(config *_config.Config, s *Server, local bool) []byte {
|
|||||||
bf.WriteUint16(uint16(channelIdx | 16))
|
bf.WriteUint16(uint16(channelIdx | 16))
|
||||||
bf.WriteUint16(ci.MaxPlayers)
|
bf.WriteUint16(ci.MaxPlayers)
|
||||||
var currentPlayers uint16
|
var currentPlayers uint16
|
||||||
s.db.QueryRow("SELECT current_players FROM servers WHERE server_id=$1", sid).Scan(¤tPlayers)
|
_ = s.db.QueryRow("SELECT current_players FROM servers WHERE server_id=$1", sid).Scan(¤tPlayers)
|
||||||
bf.WriteUint16(currentPlayers)
|
bf.WriteUint16(currentPlayers)
|
||||||
bf.WriteUint16(0)
|
bf.WriteUint16(0)
|
||||||
bf.WriteUint16(0)
|
bf.WriteUint16(0)
|
||||||
@@ -85,7 +85,7 @@ func encodeServerInfo(config *_config.Config, s *Server, local bool) []byte {
|
|||||||
bf.WriteUint16(12345)
|
bf.WriteUint16(12345)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bf.WriteUint32(uint32(channelserver.TimeAdjusted().Unix()))
|
bf.WriteUint32(uint32(gametime.Adjusted().Unix()))
|
||||||
|
|
||||||
// ClanMemberLimits requires at least 1 element with 2 columns to avoid index out of range panics
|
// ClanMemberLimits requires at least 1 element with 2 columns to avoid index out of range panics
|
||||||
// Use default value (60) if array is empty or last row is too small
|
// Use default value (60) if array is empty or last row is too small
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
ps "erupe-ce/common/pascalstring"
|
ps "erupe-ce/common/pascalstring"
|
||||||
"erupe-ce/common/stringsupport"
|
"erupe-ce/common/stringsupport"
|
||||||
_config "erupe-ce/config"
|
_config "erupe-ce/config"
|
||||||
"erupe-ce/server/channelserver"
|
"erupe-ce/common/gametime"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -50,7 +50,7 @@ func (s *Session) makeSignResponse(uid uint32) []byte {
|
|||||||
bf.WriteUint8(uint8(len(chars)))
|
bf.WriteUint8(uint8(len(chars)))
|
||||||
bf.WriteUint32(tokenID)
|
bf.WriteUint32(tokenID)
|
||||||
bf.WriteBytes([]byte(sessToken))
|
bf.WriteBytes([]byte(sessToken))
|
||||||
bf.WriteUint32(uint32(channelserver.TimeAdjusted().Unix()))
|
bf.WriteUint32(uint32(gametime.Adjusted().Unix()))
|
||||||
if s.client == PS3 {
|
if s.client == PS3 {
|
||||||
ps.Uint8(bf, fmt.Sprintf("%s/ps3", s.server.erupeConfig.PatchServerManifest), false)
|
ps.Uint8(bf, fmt.Sprintf("%s/ps3", s.server.erupeConfig.PatchServerManifest), false)
|
||||||
ps.Uint8(bf, fmt.Sprintf("%s/ps3", s.server.erupeConfig.PatchServerFile), false)
|
ps.Uint8(bf, fmt.Sprintf("%s/ps3", s.server.erupeConfig.PatchServerFile), false)
|
||||||
@@ -334,7 +334,7 @@ func (s *Session) makeSignResponse(uid uint32) []byte {
|
|||||||
|
|
||||||
if s.client == VITA || s.client == PS3 || s.client == PS4 {
|
if s.client == VITA || s.client == PS3 || s.client == PS4 {
|
||||||
var psnUser string
|
var psnUser string
|
||||||
s.server.db.QueryRow("SELECT psn_id FROM users WHERE id = $1", uid).Scan(&psnUser)
|
_ = s.server.db.QueryRow("SELECT psn_id FROM users WHERE id = $1", uid).Scan(&psnUser)
|
||||||
bf.WriteBytes(stringsupport.PaddedString(psnUser, 20, true))
|
bf.WriteBytes(stringsupport.PaddedString(psnUser, 20, true))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -385,11 +385,11 @@ func (s *Session) makeSignResponse(uid uint32) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We can just use the start timestamp as the event ID
|
// We can just use the start timestamp as the event ID
|
||||||
bf.WriteUint32(uint32(channelserver.TimeWeekStart().Unix()))
|
bf.WriteUint32(uint32(gametime.WeekStart().Unix()))
|
||||||
// Start time
|
// Start time
|
||||||
bf.WriteUint32(uint32(channelserver.TimeWeekNext().Add(-time.Duration(s.server.erupeConfig.GameplayOptions.MezFesDuration) * time.Second).Unix()))
|
bf.WriteUint32(uint32(gametime.WeekNext().Add(-time.Duration(s.server.erupeConfig.GameplayOptions.MezFesDuration) * time.Second).Unix()))
|
||||||
// End time
|
// End time
|
||||||
bf.WriteUint32(uint32(channelserver.TimeWeekNext().Unix()))
|
bf.WriteUint32(uint32(gametime.WeekNext().Unix()))
|
||||||
bf.WriteUint8(uint8(len(tickets)))
|
bf.WriteUint8(uint8(len(tickets)))
|
||||||
for i := range tickets {
|
for i := range tickets {
|
||||||
bf.WriteUint32(tickets[i])
|
bf.WriteUint32(tickets[i])
|
||||||
|
|||||||
Reference in New Issue
Block a user