Files
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

91 lines
2.8 KiB
Go

package services
import previewmodel "pvfine/internal/preview"
// PreviewService parses structured preview formats from the editor's current
// text. The current document uses caller-provided text; archive state supplies
// context for related resources without modifying the archive.
type PreviewService struct {
c *core
}
// PreviewIssue is a recoverable problem reported by a preview parser.
type PreviewIssue struct {
Severity string `json:"severity"`
Line int32 `json:"line"`
Section string `json:"section,omitempty"`
Message string `json:"message"`
}
// AniPreviewLayer is one image layer in an ANI frame.
type AniPreviewLayer struct {
Image ImageReference `json:"image"`
X int32 `json:"x"`
Y int32 `json:"y"`
}
// AniPreviewFrame is one decoded ANI frame.
type AniPreviewFrame struct {
Index int32 `json:"index"`
Delay int32 `json:"delayMs"`
Layers []AniPreviewLayer `json:"layers"`
}
// AniPreviewDocument is the structured preview model returned for .ani text.
type AniPreviewDocument struct {
Valid bool `json:"valid"`
Loop bool `json:"loop"`
Shadow bool `json:"shadow"`
FrameMax int32 `json:"frameMax"`
Frames []AniPreviewFrame `json:"frames"`
Issues []PreviewIssue `json:"issues"`
}
// NewPreviewService creates the Wails-facing preview service.
func NewPreviewService(cores ...*core) *PreviewService {
service := &PreviewService{}
if len(cores) > 0 {
service.c = cores[0]
}
return service
}
// ParseANI parses the current editor text. Semantic and structural problems
// are returned in Issues so the caller can retain the last valid preview;
// the RPC error is reserved for service-level failures.
func (s *PreviewService) ParseANI(text string) (*AniPreviewDocument, error) {
parsed := previewmodel.ParseANI(text)
result := &AniPreviewDocument{
Valid: parsed.Valid,
Loop: parsed.Loop,
Shadow: parsed.Shadow,
FrameMax: parsed.FrameMax,
Frames: make([]AniPreviewFrame, 0, len(parsed.Frames)),
Issues: make([]PreviewIssue, 0, len(parsed.Issues)),
}
for _, frame := range parsed.Frames {
converted := AniPreviewFrame{
Index: frame.Index,
Delay: frame.Delay,
Layers: make([]AniPreviewLayer, 0, len(frame.Layers)),
}
for _, layer := range frame.Layers {
converted.Layers = append(converted.Layers, AniPreviewLayer{
Image: ImageReference{Path: layer.Path, Index: layer.Index},
X: layer.X,
Y: layer.Y,
})
}
result.Frames = append(result.Frames, converted)
}
for _, issue := range parsed.Issues {
result.Issues = append(result.Issues, PreviewIssue{
Severity: string(issue.Severity),
Line: int32(issue.Line),
Section: issue.Section,
Message: issue.Message,
})
}
return result, nil
}