DNF90 服务端与启动器完整源码(含 GM 工具功能增强)
服务端(Go): - GM 塞背包/带属性装备发放:在线角色推送 op14 增量物品行,背包实时刷新,无需回角色选择界面 - GM 改金币/改等级:去掉在线拒绝,落库后推送 op14 钱包/op37 等级状态,在线实时刷新 - 等级端点统一切换到新版 GMSetCharacterLevel(自带在线刷新) - 无限/锁死疲劳模式 + 燃烧疲劳:每房间消耗 2 点、打怪与通关经验双倍 - 燃烧疲劳开关时给所有在线角色推送系统提示(op12 mode 0) - 深渊史诗掉率:GM 全局倍率 + 城镇增益药剂窗口倍率,真实接入掉落结算 启动器(Python/JS): - 标题栏自绘、窗口 1204x717、禁止拖拽改大小、仅最小化/关闭 - GM 工具:疲劳与燃烧、深渊史诗掉率、拍卖行上架(单一定价对齐) - 拍卖行上架前端对齐服务端单一价格语义,修复 400 报错
This commit is contained in:
commit
645b64fe21
4388 files changed
+1405457
No files matched your search
@@ -0,0 +1,125 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"pvfine/internal/pvf"
|
||||
)
|
||||
|
||||
func newEditorSaveFixture(t *testing.T) (string, *core, int32, []byte) {
|
||||
t.Helper()
|
||||
|
||||
built := pvf.New()
|
||||
index, err := built.AddFileText("test/example.equ", "[name]\n`before`", pvf.TypeScript)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var encoded bytes.Buffer
|
||||
if err := built.SaveTo(&encoded); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
sourcePath := filepath.Join(t.TempDir(), "source.pvf")
|
||||
original := encoded.Bytes()
|
||||
if err := os.WriteFile(sourcePath, original, 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
archive, err := pvf.Open(sourcePath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
core := NewCore()
|
||||
if err := core.setArchive(archive); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(core.closeArchive)
|
||||
return sourcePath, core, index, append([]byte(nil), original...)
|
||||
}
|
||||
|
||||
func TestEditorServiceSaveBacksUpSourceByDefault(t *testing.T) {
|
||||
sourcePath, core, index, original := newEditorSaveFixture(t)
|
||||
editor := NewEditorService(core)
|
||||
if err := editor.SetText(index, "[name]\n`after`\n"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := editor.Save(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
backup, err := os.ReadFile(sourcePath + ".bak")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(backup, original) {
|
||||
t.Fatal("source backup does not contain the original archive")
|
||||
}
|
||||
saved, err := pvf.Open(sourcePath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
savedIndex, ok := saved.Find("test/example.equ")
|
||||
if !ok {
|
||||
t.Fatal("saved file is missing")
|
||||
}
|
||||
text, err := saved.Text(savedIndex)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(text, "after") {
|
||||
t.Fatalf("saved text = %q", text)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEditorServiceSaveCanDisableSourceBackup(t *testing.T) {
|
||||
sourcePath, core, index, _ := newEditorSaveFixture(t)
|
||||
settingsService := newSettingsService(filepath.Join(t.TempDir(), "settings.json"))
|
||||
settings := DefaultAppSettings()
|
||||
settings.BackupSourceOnSave = false
|
||||
if err := settingsService.SaveSettings(settings); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
editor := NewEditorService(core, settingsService)
|
||||
if err := editor.SetText(index, "[name]\n`after`\n"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := editor.Save(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := os.Stat(sourcePath + ".bak"); !os.IsNotExist(err) {
|
||||
t.Fatalf("source backup exists or stat failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBackupSourceProgressCountsBytes(t *testing.T) {
|
||||
sourcePath := filepath.Join(t.TempDir(), "source.pvf")
|
||||
original := bytes.Repeat([]byte("backup data"), 300000)
|
||||
if err := os.WriteFile(sourcePath, original, 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var lastCount int64
|
||||
var synced bool
|
||||
if err := backupSourceFileWithProgress(sourcePath, func(p pvf.SaveProgress) {
|
||||
if p.Phase == "backup" {
|
||||
if p.Total != int64(len(original)) || p.Done < lastCount || p.Done > p.Total {
|
||||
t.Fatalf("invalid backup progress: %+v", p)
|
||||
}
|
||||
lastCount = p.Done
|
||||
} else if p.Phase == "backup-sync" {
|
||||
if lastCount != int64(len(original)) {
|
||||
t.Fatal("sync preceded full copy")
|
||||
}
|
||||
synced = true
|
||||
}
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
backup, err := os.ReadFile(sourcePath + ".bak")
|
||||
if err != nil || !bytes.Equal(backup, original) || !synced {
|
||||
t.Fatal("backup progress changed backup content or omitted sync")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user