Files
90CNServer/server/internal/platform/playerloop/online_registry.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

85 lines
2.1 KiB
Go

package playerloop
import (
"strings"
"sync"
"time"
)
// OnlineRecord 记录账号在线状态和最近变更时间。
type OnlineRecord struct {
AccountID string `json:"account_id"`
Online bool `json:"online"`
UpdatedAt time.Time `json:"updated_at"`
}
// OnlineRegistry 在内存中维护账号在线状态。
type OnlineRegistry struct {
mu sync.RWMutex
records map[string]OnlineRecord
now func() time.Time
}
// NewOnlineRegistry 使用系统时钟创建在线状态表。
func NewOnlineRegistry() *OnlineRegistry {
return NewOnlineRegistryWithClock(time.Now)
}
// NewOnlineRegistryWithClock 使用指定时钟创建在线状态表,便于测试和回放。
func NewOnlineRegistryWithClock(now func() time.Time) *OnlineRegistry {
if now == nil {
now = time.Now
}
return &OnlineRegistry{
records: make(map[string]OnlineRecord),
now: now,
}
}
// MarkOnline 标记账号在线并返回新状态。
func (r *OnlineRegistry) MarkOnline(accountID string) OnlineRecord {
return r.set(accountID, true)
}
// MarkOffline 标记账号离线并返回新状态。
func (r *OnlineRegistry) MarkOffline(accountID string) OnlineRecord {
return r.set(accountID, false)
}
// IsOnline 判断账号当前是否在线。
func (r *OnlineRegistry) IsOnline(accountID string) bool {
accountID = strings.TrimSpace(accountID)
if r == nil || accountID == "" {
return false
}
r.mu.RLock()
defer r.mu.RUnlock()
return r.records[accountID].Online
}
// Snapshot 返回在线状态表的当前副本。
func (r *OnlineRegistry) Snapshot() []OnlineRecord {
if r == nil {
return nil
}
r.mu.RLock()
defer r.mu.RUnlock()
out := make([]OnlineRecord, 0, len(r.records))
for _, record := range r.records {
out = append(out, record)
}
return out
}
func (r *OnlineRegistry) set(accountID string, online bool) OnlineRecord {
accountID = strings.TrimSpace(accountID)
if r == nil || accountID == "" {
return OnlineRecord{}
}
record := OnlineRecord{AccountID: accountID, Online: online, UpdatedAt: r.now().UTC()}
r.mu.Lock()
r.records[accountID] = record
r.mu.Unlock()
return record
}