feat(config): add RealClientMode infrastructure for multi-version support

Add client version mode support to enable version-specific behavior:

- Add Mode type with constants for all game versions (S1.0 through ZZ)
- Add ClientMode (string) and RealClientMode (Mode) to Config
- Add ClanMemberLimits to GameplayOptions for configurable clan sizes
- Add MaximumFP to GameplayOptions for festa points cap
- Parse ClientMode string to RealClientMode enum in LoadConfig
- Set sensible defaults (ZZ for mode, standard limits for clans)
- Update config.example.json with new fields

This enables cherry-picking version-specific fixes from main branch.
This commit is contained in:
Houmgaor
2026-01-30 01:08:37 +01:00
parent 94175e6e85
commit 279d8b4aa0
2 changed files with 95 additions and 9 deletions

View File

@@ -12,6 +12,7 @@
"ScreenshotAPIURL": "", "ScreenshotAPIURL": "",
"DeleteOnSaveCorruption": false, "DeleteOnSaveCorruption": false,
"DevMode": true, "DevMode": true,
"ClientMode": "ZZ",
"DevModeOptions": { "DevModeOptions": {
"AutoCreateAccount": true, "AutoCreateAccount": true,
"CleanDB": false, "CleanDB": false,
@@ -39,6 +40,7 @@
"DisableBoostTime": false, "DisableBoostTime": false,
"BoostTimeDuration": 120, "BoostTimeDuration": 120,
"ClanMealDuration": 3600, "ClanMealDuration": 3600,
"ClanMemberLimits": [[0, 30], [3, 40], [7, 50], [10, 60]],
"BonusQuestAllowance": 3, "BonusQuestAllowance": 3,
"DailyQuestAllowance": 1 "DailyQuestAllowance": 1
}, },

View File

@@ -11,6 +11,68 @@ import (
"github.com/spf13/viper" "github.com/spf13/viper"
) )
// Mode represents the client version/mode
type Mode int
// Client version constants
const (
S1 Mode = iota + 1
S15
S2
S25
S3
S35
S4
S5
S55
S6
S7
S8
S85
S9
S10
F1
F2
F3
F4
F5
G1
G2
G3
G31
G32
GG
G5
G51
G52
G6
G61
G7
G8
G81
G9
G91
G10
G101
Z1
Z2
ZZ
)
var versionStrings = []string{
"S1.0", "S1.5", "S2.0", "S2.5", "S3.0", "S3.5", "S4.0", "S5.0", "S5.5", "S6.0",
"S7.0", "S8.0", "S8.5", "S9.0", "S10", "FW.1", "FW.2", "FW.3", "FW.4", "FW.5",
"G1", "G2", "G3", "G3.1", "G3.2", "GG", "G5", "G5.1", "G5.2", "G6", "G6.1",
"G7", "G8", "G8.1", "G9", "G9.1", "G10", "G10.1", "Z1", "Z2", "ZZ",
}
func (m Mode) String() string {
if m < 1 || int(m) > len(versionStrings) {
return "Unknown"
}
return versionStrings[m-1]
}
// Config holds the global server-wide config. // Config holds the global server-wide config.
type Config struct { type Config struct {
Host string `mapstructure:"Host"` Host string `mapstructure:"Host"`
@@ -24,6 +86,8 @@ type Config struct {
ScreenshotAPIURL string // Destination for screenshots uploaded to BBS ScreenshotAPIURL string // Destination for screenshots uploaded to BBS
DeleteOnSaveCorruption bool // Attempts to save corrupted data will flag the save for deletion DeleteOnSaveCorruption bool // Attempts to save corrupted data will flag the save for deletion
DevMode bool DevMode bool
ClientMode string // Client version string (e.g., "ZZ", "G10", "S6.0")
RealClientMode Mode // Parsed client mode for version checks
DevModeOptions DevModeOptions DevModeOptions DevModeOptions
GameplayOptions GameplayOptions GameplayOptions GameplayOptions
@@ -66,10 +130,12 @@ type GameplayOptions struct {
FeaturedWeapons int // Number of Active Feature weapons to generate daily FeaturedWeapons int // Number of Active Feature weapons to generate daily
MaximumNP int // Maximum number of NP held by a player MaximumNP int // Maximum number of NP held by a player
MaximumRP uint16 // Maximum number of RP held by a player MaximumRP uint16 // Maximum number of RP held by a player
MaximumFP uint32 // Maximum number of Festa Points held by a player
DisableLoginBoost bool // Disables the Login Boost system DisableLoginBoost bool // Disables the Login Boost system
DisableBoostTime bool // Disables the daily NetCafe Boost Time DisableBoostTime bool // Disables the daily NetCafe Boost Time
BoostTimeDuration int // The number of minutes NetCafe Boost Time lasts for BoostTimeDuration int // The number of minutes NetCafe Boost Time lasts for
ClanMealDuration int // Seconds that a Clan Meal can be activated for after cooking ClanMealDuration int // Seconds that a Clan Meal can be activated for after cooking
ClanMemberLimits [][]uint8 // Array of maximum Clan Members -> [[Rank, Members], ...]
BonusQuestAllowance uint32 // Number of Bonus Point Quests to allow daily BonusQuestAllowance uint32 // Number of Bonus Point Quests to allow daily
DailyQuestAllowance uint32 // Number of Daily Quests to allow daily DailyQuestAllowance uint32 // Number of Daily Quests to allow daily
} }
@@ -232,6 +298,24 @@ func LoadConfig() (*Config, error) {
c.Host = getOutboundIP4().To4().String() c.Host = getOutboundIP4().To4().String()
} }
// Parse ClientMode string to RealClientMode
c.RealClientMode = ZZ // Default to ZZ
if c.ClientMode != "" {
clientModeUpper := strings.ToUpper(c.ClientMode)
for i, vs := range versionStrings {
if clientModeUpper == vs {
c.RealClientMode = Mode(i + 1)
c.ClientMode = vs // Normalize the string
break
}
}
}
// Set default ClanMemberLimits if not configured
if len(c.GameplayOptions.ClanMemberLimits) == 0 {
c.GameplayOptions.ClanMemberLimits = [][]uint8{{0, 30}, {3, 40}, {7, 50}, {10, 60}}
}
return c, nil return c, nil
} }