Files
90CNServer/server/cmd/server/control/database_mode_test.go
T
hanfuit 645b64fe21 DNF90 服务端与启动器完整源码(含 GM 工具功能增强)
服务端(Go):
- GM 塞背包/带属性装备发放:在线角色推送 op14 增量物品行,背包实时刷新,无需回角色选择界面
- GM 改金币/改等级:去掉在线拒绝,落库后推送 op14 钱包/op37 等级状态,在线实时刷新
- 等级端点统一切换到新版 GMSetCharacterLevel(自带在线刷新)
- 无限/锁死疲劳模式 + 燃烧疲劳:每房间消耗 2 点、打怪与通关经验双倍
- 燃烧疲劳开关时给所有在线角色推送系统提示(op12 mode 0)
- 深渊史诗掉率:GM 全局倍率 + 城镇增益药剂窗口倍率,真实接入掉落结算

启动器(Python/JS):
- 标题栏自绘、窗口 1204x717、禁止拖拽改大小、仅最小化/关闭
- GM 工具:疲劳与燃烧、深渊史诗掉率、拍卖行上架(单一定价对齐)
- 拍卖行上架前端对齐服务端单一价格语义,修复 400 报错
2026-11-04 14:31:55 +08:00

106 lines
3.0 KiB
Go

package main
import (
"bytes"
"context"
"os"
"testing"
)
func TestSelectDatabaseModePreservesInstallationAndClient(t *testing.T) {
root := t.TempDir()
paths := newProjectPaths(root)
if err := paths.ensureDirectories(); err != nil {
t.Fatal(err)
}
cfg := validTestInstance()
cfg.Database = databaseConfig{
Mode: databaseModeSQLite,
Path: "data/dnf90.db",
Name: "dnf_local",
}
cfg.Client.Directory = `D:\Games\DNF`
data, err := marshalInstance(cfg)
if err != nil {
t.Fatal(err)
}
if err := writeFile(paths.instance, data, 0o600); err != nil {
t.Fatal(err)
}
var output bytes.Buffer
controller := newController(paths, &output, &output)
if err := controller.selectDatabaseMode(context.Background(), "mysql", false); err != nil {
t.Fatalf("select MySQL: %v", err)
}
selected, err := decodeInstance(paths.instance)
if err != nil {
t.Fatal(err)
}
if selected.Database.Mode != databaseModePortable ||
selected.Database.Host != "127.0.0.1" ||
selected.Database.Port != 13306 ||
selected.Database.User != "root" ||
selected.Database.Password == "" {
t.Fatalf("portable database profile = %+v", selected.Database)
}
if selected.InstallationID != cfg.InstallationID ||
selected.Server.AccountID != cfg.Server.AccountID ||
selected.Client.Directory != cfg.Client.Directory {
t.Fatalf("mode switch changed installation identity: %+v", selected)
}
password := selected.Database.Password
if err := controller.selectDatabaseMode(context.Background(), "sqlite", false); err != nil {
t.Fatalf("select SQLite: %v", err)
}
selected, err = decodeInstance(paths.instance)
if err != nil {
t.Fatal(err)
}
if selected.Database.Mode != databaseModeSQLite || selected.Database.Path != "data/dnf90.db" {
t.Fatalf("SQLite database profile = %+v", selected.Database)
}
if selected.Database.Password != password {
t.Fatal("portable MySQL credential was not retained for switching back")
}
}
func TestNormalizeDatabaseModeAcceptsPublishedNames(t *testing.T) {
for input, want := range map[string]string{
"SQLite": databaseModeSQLite,
"SQLiet": databaseModeSQLite,
"MySQL": databaseModePortable,
} {
got, err := normalizeDatabaseMode(input)
if err != nil || got != want {
t.Fatalf("normalizeDatabaseMode(%q) = %q, %v", input, got, err)
}
}
if _, err := normalizeDatabaseMode("unknown"); err == nil {
t.Fatal("unknown database mode was accepted")
}
}
func TestSelectDatabaseModeRejectsUnknownModeWithoutWriting(t *testing.T) {
root := t.TempDir()
paths := newProjectPaths(root)
if err := paths.ensureDirectories(); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(paths.instance, []byte("sentinel"), 0o600); err != nil {
t.Fatal(err)
}
controller := newController(paths, &bytes.Buffer{}, &bytes.Buffer{})
if err := controller.selectDatabaseMode(context.Background(), "unknown", false); err == nil {
t.Fatal("unknown database mode was accepted")
}
data, err := os.ReadFile(paths.instance)
if err != nil {
t.Fatal(err)
}
if string(data) != "sentinel" {
t.Fatalf("invalid selection changed instance.json: %q", data)
}
}