DNF90 服务端与启动器完整源码(含 GM 工具功能增强)

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

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

No files matched your search

@@ -0,0 +1,152 @@
package app
import (
"context"
"fmt"
"log/slog"
"longheng.io/server/internal/platform/audit"
"longheng.io/server/internal/platform/bilog"
"longheng.io/server/internal/platform/config"
"longheng.io/server/internal/platform/datatable"
"longheng.io/server/internal/platform/health"
"longheng.io/server/internal/platform/httpx"
"longheng.io/server/internal/platform/logiclog"
"longheng.io/server/internal/platform/logx"
"longheng.io/server/internal/platform/metrics"
"longheng.io/server/internal/platform/otelx"
"longheng.io/server/internal/platform/pvf"
"longheng.io/server/internal/platform/ratelimit"
"longheng.io/server/internal/platform/scheduler"
"longheng.io/server/internal/platform/servergroup"
"longheng.io/server/internal/platform/statesync"
"longheng.io/server/internal/platform/tracing"
)
type platformFoundation struct {
cfg config.ServiceConfig
logger *slog.Logger
otelShutdown otelx.Shutdown
pvfArchive *pvf.Archive
dataTables *datatable.Registry
dataTableViews *datatable.ViewManager
stateSyncStore statesync.Store
serverGroupManager *servergroup.Manager
serverGroupStore servergroup.Store
serverGroupArchives servergroup.MergeArchiveStore
auditLogger *audit.Logger
logicLogger *logiclog.Logger
biLogger *bilog.Logger
healthSvc *health.Service
metricsRegistry *metrics.Registry
tracer *tracing.Tracer
rateLimiter *ratelimit.Limiter
adminTimeouts httpx.Timeouts
adminServer *httpx.Server
schedulerSvc *scheduler.Scheduler
}
func newPlatformBase(serviceName, configPath string) (*platformFoundation, error) {
cfg, err := config.Load(configPath, serviceName)
if err != nil {
return nil, fmt.Errorf("load config: %w", err)
}
pvfArchive, err := newPVFArchive(cfg)
if err != nil {
return nil, err
}
logger := logx.New(cfg.Service.Name, cfg.Service.NodeID, cfg.Service.Environment)
otelShutdown, err := setupOTel(cfg, logger)
if err != nil {
return nil, fmt.Errorf("setup opentelemetry: %w", err)
}
foundation := &platformFoundation{
cfg: cfg,
logger: logger,
otelShutdown: otelShutdown,
pvfArchive: pvfArchive,
}
if foundation.dataTables, err = newDataTables(cfg); err != nil {
_ = foundation.close(context.Background())
return nil, err
}
if foundation.dataTableViews, err = datatable.NewViewManager(); err != nil {
_ = foundation.close(context.Background())
return nil, err
}
if foundation.stateSyncStore, err = newStateSyncStore(cfg); err != nil {
_ = foundation.close(context.Background())
return nil, err
}
foundation.serverGroupManager, foundation.serverGroupStore, foundation.serverGroupArchives, err = newGroupManager(context.Background(), cfg)
if err != nil {
_ = foundation.close(context.Background())
return nil, err
}
if foundation.auditLogger, err = newAuditLogger(cfg); err != nil {
_ = foundation.close(context.Background())
return nil, err
}
if foundation.logicLogger, err = newLogicLogger(cfg); err != nil {
_ = foundation.close(context.Background())
return nil, err
}
if foundation.biLogger, err = newBILogger(cfg); err != nil {
_ = foundation.close(context.Background())
return nil, err
}
foundation.healthSvc = health.New(cfg.Service.Name)
foundation.metricsRegistry = metrics.New()
foundation.tracer = tracing.New(cfg.Tracing.Enabled || cfg.OTel.Enabled, cfg.Tracing.MaxSpans, logger)
if foundation.rateLimiter, err = newRateLimiter(cfg); err != nil {
_ = foundation.close(context.Background())
return nil, err
}
foundation.adminTimeouts = httpx.Timeouts{
ReadTimeout: cfg.Admin.ReadTimeout(),
ReadHeaderTimeout: cfg.Admin.ReadHeaderTimeout(),
WriteTimeout: cfg.Admin.WriteTimeout(),
IdleTimeout: cfg.Admin.IdleTimeout(),
}
foundation.adminServer = httpx.New("admin-http", cfg.Admin.Listen, logger, foundation.adminTimeouts)
foundation.schedulerSvc = scheduler.New("scheduler", logger)
return foundation, nil
}
func (f *platformFoundation) close(ctx context.Context) error {
if f == nil {
return nil
}
if ctx == nil {
ctx = context.Background()
}
var err error
if f.stateSyncStore != nil {
err = f.stateSyncStore.Close()
f.stateSyncStore = nil
}
if f.auditLogger != nil {
if closeErr := f.auditLogger.Close(); closeErr != nil && err == nil {
err = closeErr
}
f.auditLogger = nil
}
if f.logicLogger != nil {
if closeErr := f.logicLogger.Close(); closeErr != nil && err == nil {
err = closeErr
}
f.logicLogger = nil
}
if f.biLogger != nil {
if closeErr := f.biLogger.Close(); closeErr != nil && err == nil {
err = closeErr
}
f.biLogger = nil
}
if closeErr := shutdownOTel(ctx, f.otelShutdown); closeErr != nil && err == nil {
err = closeErr
}
f.otelShutdown = nil
return err
}